Compare commits
422 Commits
v0.5.0
..
aa31db7e07
| Author | SHA1 | Date | |
|---|---|---|---|
|
aa31db7e07
|
|||
|
8c6dde7d86
|
|||
|
738e29059b
|
|||
|
2eb81c4a8b
|
|||
|
88998d1019
|
|||
|
a1fc099c24
|
|||
|
2fe365bef8
|
|||
|
efb1b7b96b
|
|||
|
d915f9e3c1
|
|||
|
11ebf3c155
|
|||
|
abf5d425fd
|
|||
|
1e3d52482a
|
|||
|
0fb72f8226
|
|||
|
0701c370b4
|
|||
|
0bdaa9441f
|
|||
|
4ba1bd8a24
|
|||
|
b484242e4c
|
|||
|
a756394e30
|
|||
|
0faf7b850d
|
|||
|
eeb9f7083b
|
|||
|
b6a5b340f1
|
|||
|
209257c7b1
|
|||
|
4e88cebe28
|
|||
|
738b600fa6
|
|||
|
f67538e5ab
|
|||
|
18bb3d3440
|
|||
|
04cd3c890b
|
|||
|
ef8f5865e2
|
|||
|
493e9bb2a5
|
|||
|
3eff135349
|
|||
|
7ac753d824
|
|||
|
9add71ff13
|
|||
|
7154c3a652
|
|||
|
36ac924d77
|
|||
|
5e4d3ff011
|
|||
|
fd287b09b0
|
|||
|
07c1f70df3
|
|||
|
8c398b6360
|
|||
|
e43c2e477a
|
|||
|
6078072915
|
|||
|
1902e2d040
|
|||
|
702e6f2f63
|
|||
|
01938a0f28
|
|||
|
5d017fbb48
|
|||
|
a3ed9476ae
|
|||
|
a22faad992
|
|||
|
06fe1f9471
|
|||
|
e2ff2c03f8
|
|||
|
7ca9a19d3b
|
|||
|
f5b69d6b4d
|
|||
|
4f244618ca
|
|||
|
b7a20a000a
|
|||
|
0094be475f
|
|||
|
3e508c9337
|
|||
|
edd3c08247
|
|||
|
bf6b2f718c
|
|||
|
984a073730
|
|||
|
aa4babff56
|
|||
|
7f620d469b
|
|||
|
33782c59a8
|
|||
|
5669830510
|
|||
|
99c6cff068
|
|||
|
9b395a304d
|
|||
|
01912bcef3
|
|||
|
e0b85fc936
|
|||
|
73f6e07e47
|
|||
|
534b9923ae
|
|||
|
c66faa22dc
|
|||
|
cf666eb2c6
|
|||
|
76861508c9
|
|||
|
beebb39050
|
|||
|
3d7ba424f1
|
|||
|
84eb82b355
|
|||
|
1fbdcd66d1
|
|||
|
5b65496684
|
|||
|
ca808b4c08
|
|||
|
84c1753ed5
|
|||
|
c8d9f89d59
|
|||
|
e3531b4dcf
|
|||
|
b939868d28
|
|||
|
7630b3e75c
|
|||
| 3292f8e0a5 | |||
|
cf1c06e632
|
|||
|
49f2932b30
|
|||
|
5fd786dd3d
|
|||
|
f5967c7771
|
|||
|
eee0e86131
|
|||
|
51dfd2a655
|
|||
|
d9cf0c4b08
|
|||
|
b4c65f7a19
|
|||
|
1c0e836a92
|
|||
|
2da196c091
|
|||
|
69648afe27
|
|||
|
454f5c03f3
|
|||
|
406642723e
|
|||
|
2469b713c7
|
|||
|
b6ad7a575d
|
|||
|
f3b410d146
|
|||
|
095d0f3d8a
|
|||
|
5f445e046f
|
|||
|
96ab2bdc1b
|
|||
|
cb175e3b51
|
|||
|
7965b970d9
|
|||
|
0a21f10b04
|
|||
|
49aa9fad41
|
|||
|
8f7d3bd13c
|
|||
|
f7fb249d43
|
|||
|
d9498ffb21
|
|||
|
0177fa6906
|
|||
|
c3f6cb8f46
|
|||
|
7facdce6b6
|
|||
|
c11eb352fe
|
|||
|
0e427dc4ba
|
|||
|
f1914f6bd4
|
|||
|
dba6304f51
|
|||
|
e40a8bba72
|
|||
|
c057249e52
|
|||
|
d906713d7d
|
|||
| ff3419a714 | |||
|
a5899da4fb
|
|||
|
dedcef8ac5
|
|||
|
d658f1d2fe
|
|||
|
6b4a45874f
|
|||
|
7839e1dbd9
|
|||
|
78c3932f36
|
|||
|
11334149b0
|
|||
|
4caa035528
|
|||
|
f30e81af08
|
|||
|
4c75655f58
|
|||
|
f865892c28
|
|||
|
ebeb9c9b7d
|
|||
|
ab2b927fcb
|
|||
|
7e5ff2ba1f
|
|||
|
ed59051f3d
|
|||
| e98bf56a2b | |||
| fb510b1a4f | |||
|
6c17462040
|
|||
|
1536cf384c
|
|||
|
d6842d7e29
|
|||
|
fbc0acda2a
|
|||
|
0327d041b6
|
|||
|
6a01fd4fbd
|
|||
| d822180205 | |||
|
89d0fdce26
|
|||
|
b3ecdce979
|
|||
|
3873821a31
|
|||
|
9c2801b643
|
|||
|
d78820dcd4
|
|||
|
d43c4232a2
|
|||
|
f41c85b703
|
|||
|
9e056bdcf0
|
|||
|
d6022b9f98
|
|||
|
6fc1abf94a
|
|||
|
92ea0f624e
|
|||
|
c3fd8fbc1c
|
|||
|
7fd3f7761c
|
|||
|
05e19098b2
|
|||
|
60067ae757
|
|||
|
c72003b0b6
|
|||
|
7c9d500116
|
|||
|
6b2c87b562
|
|||
|
b2dbdfb4b1
|
|||
|
063e198f96
|
|||
|
73cbe16ec1
|
|||
|
bdea854a9f
|
|||
|
9b4c800597
|
|||
|
eb4d1c02f4
|
|||
|
c428990900
|
|||
|
03b9cc70b9
|
|||
|
3fa0eb832c
|
|||
|
83f66e1061
|
|||
|
741b9c364c
|
|||
|
b6f6f456db
|
|||
|
00a6cf74d7
|
|||
|
d35ca352ca
|
|||
| 57dc1cb252 | |||
|
101a9cdd6e
|
|||
|
c5f52e1efb
|
|||
|
470149b606
|
|||
|
02062c5a50
|
|||
|
e6e99b6926
|
|||
|
15a293204f
|
|||
|
ecf3780aed
|
|||
|
e798747135
|
|||
|
60493728a0
|
|||
|
25d6370b20
|
|||
|
d67f845af5
|
|||
|
920a14cabe
|
|||
|
58bdd2e584
|
|||
|
ce6f53ad05
|
|||
|
96f8007d53
|
|||
|
32a55652fe
|
|||
|
2b92e6c98b
|
|||
|
cfa654bcd8
|
|||
|
d0f5ae39e2
|
|||
|
2bb8cf5f73
|
|||
|
fbac446859
|
|||
|
f91cf2e346
|
|||
|
b6b33ab7e3
|
|||
|
c1902a69d1
|
|||
|
812a8e101c
|
|||
|
655ee2a599
|
|||
|
128a8f9a9c
|
|||
|
b1be9443e7
|
|||
|
7b12c69ebf
|
|||
|
69ad584137
|
|||
|
313058e70a
|
|||
|
ea96d9ba3d
|
|||
|
7884adc7c1
|
|||
|
948466d771
|
|||
|
3894c98b5b
|
|||
|
5e9c31595e
|
|||
|
39d9b25e47
|
|||
|
b86f76ddb9
|
|||
|
7f267a10a1
|
|||
|
cdafdff281
|
|||
|
60ad83d6d9
|
|||
|
44c03ccf4f
|
|||
|
af933bbb29
|
|||
|
1f127ee990
|
|||
|
88a9a7709f
|
|||
| e8d92d1b01 | |||
| ddbfd03e75 | |||
|
d1c7f09015
|
|||
|
d2f8f995f0
|
|||
|
5ef9a397ca
|
|||
|
325ab1f45e
|
|||
|
4cfaa2dc77
|
|||
|
6abe2c5536
|
|||
|
03cfd59962
|
|||
|
4d7d5e5e53
|
|||
|
3779b940ae
|
|||
|
d2e541c5c0
|
|||
|
621c90427c
|
|||
|
486001ee85
|
|||
|
c7a2ec084f
|
|||
|
d4e0d48198
|
|||
|
07f23bab5e
|
|||
|
b11797ea1c
|
|||
|
70c2d411ae
|
|||
|
f82c9aff40
|
|||
|
a935add2a7
|
|||
|
8a37a88ffd
|
|||
|
8f66cac680
|
|||
|
0a40ddd2e4
|
|||
|
d5e0728532
|
|||
|
25c0885dcc
|
|||
|
f56ed7d005
|
|||
|
d79e4b9dff
|
|||
|
cdd829199f
|
|||
|
e3c644b8ca
|
|||
|
5cb8070da1
|
|||
|
66801b5d07
|
|||
|
f2de196e22
|
|||
|
2eba530895
|
|||
| 3baa3102a3 | |||
| 2d4fad596c | |||
| 7259e59d2a | |||
| cec04c4597 | |||
| a7f5677195 | |||
| 6075f0a190 | |||
| 15310a9e2c | |||
| f7df54f2f7 | |||
| 212d4bace4 | |||
| f4b3267c89 | |||
| 9eeeb11871 | |||
| b8db3f689d | |||
| 3b21ce2aa5 | |||
| 9bf4fcd943 | |||
| c1f5cfbbda | |||
| 46517a4e15 | |||
| efbe76e1fc | |||
| 245c567d30 | |||
| cbb3d2c34a | |||
| bddec85fa5 | |||
| 96acbc6bf0 | |||
| 0735a31190 | |||
| 986c64ff13 | |||
| 831426d418 | |||
| b99e3fc030 | |||
| 012734f70a | |||
| f591a9635e | |||
| 7c099bf589 | |||
| 32d3cee907 | |||
| 86539c4bb8 | |||
| 14549afd52 | |||
| 667c843fc0 | |||
| 680a52982c | |||
| 52efb1a775 | |||
| c88931d318 | |||
| 2183ed62d1 | |||
| cc8bd040b9 | |||
| a2a464151f | |||
| c9a3f247e7 | |||
| d167502b7b | |||
| 0d9927bb99 | |||
| c9858ce615 | |||
| cccaa1dbe7 | |||
| acd951e981 | |||
| 10d80d58fd | |||
| f196c375d6 | |||
| cc62c89b05 | |||
| 3266cdeb08 | |||
| 6605c62015 | |||
| 704fdbd145 | |||
| 93e76a65a1 | |||
| b3ca7ebddb | |||
| 091fc0b7b7 | |||
| 874f5ba08e | |||
| 5fdfe94b88 | |||
| c02b168749 | |||
| 6ababd919d | |||
| 86b2b2d772 | |||
| 2aa2c3ccee | |||
| 70645a8431 | |||
| ca4b2f2637 | |||
| 7fce8f9b23 | |||
| e5b3b332f6 | |||
| 3e59762443 | |||
| 2ea8a48f28 | |||
| 3c07471620 | |||
| 23e2c1144f | |||
| 313f5e2dda | |||
| 26c35e55d8 | |||
| 878adc0eb7 | |||
| d353767b2c | |||
| 33baeaa62d | |||
| 591b7a5bf1 | |||
| 0bc993532b | |||
| 09379e7231 | |||
| 1a45ce9dc1 | |||
| 95df054dfb | |||
| 5b49553c6d | |||
| 6508940d11 | |||
| 71d89eaaba | |||
| 9619b7908f | |||
| 304129d793 | |||
| 5df435c21a | |||
| 2719c7320a | |||
| a84bae189c | |||
| d82c7c2535 | |||
| 2bc832ed95 | |||
| b5a0f0635b | |||
| 7426aa4bcb | |||
| ba9649382e | |||
| 9c64e97d8b | |||
| 4b1cd3cf44 | |||
| 4a0f002503 | |||
| c4f8c6e102 | |||
| 421308423f | |||
| 0550de2093 | |||
| dddf72e1da | |||
| e23820adf2 | |||
| fea4411aa6 | |||
| b814a38c59 | |||
| 1a3476e4fb | |||
| ecd4d6587c | |||
| 0938119e99 | |||
| 9f15f01871 | |||
| f09cbd2b32 | |||
| 77c1a06277 | |||
| 600f5d1484 | |||
| 7f71317acd | |||
| 865ef5827b | |||
| e5d5bf6c53 | |||
| 7b08d1ef96 | |||
| 9d363b38c7 | |||
| 2f3586cbbf | |||
| 843abe0621 | |||
| 474c5bc76f | |||
| b49a27f886 | |||
| 6f77b3f46e | |||
| a835012673 | |||
| 3f1e8003f8 | |||
| 8475707e75 | |||
| 8a240b1c3f | |||
| 59a3e3012b | |||
| c13142f971 | |||
| a468ee1154 | |||
| 1b504e211a | |||
| 29536f6291 | |||
| 4ef483126d | |||
| 8d2961f3ee | |||
| f1146bb2b9 | |||
| 2daa014c99 | |||
| ebe642f44a | |||
| 25ad254e84 | |||
| 947a7871c2 | |||
| 6421a677eb | |||
| 950893f4a2 | |||
| a10948614d | |||
| 39fc863e22 | |||
| df8b326d89 | |||
| 591f204b67 | |||
| 316ebd6d25 | |||
| 4e707ae08e | |||
| 1ef554c759 | |||
| 367e7d90fd | |||
| 6e7a89763c | |||
| 9dd3836802 | |||
| f822546971 | |||
| 4bf338f91a | |||
| 16577ddc5e | |||
| 384ae73c80 | |||
| d4c932b8ac | |||
| 743e42d4f8 | |||
| 6be2651106 | |||
| 2a2d20a25c | |||
| 882942385b | |||
| 0aa908c8d3 | |||
| 4c179c9269 | |||
| a4fe91ffda | |||
| dc500207ef | |||
| c1e3c3699b | |||
| 52e9f5fc70 | |||
| c85cddb5b4 | |||
| 477b53124d | |||
| 650dbd92e0 | |||
| 88288a98b6 | |||
| 377ab91af7 | |||
| acfc7685f4 | |||
| 5636010e1e |
@@ -21,25 +21,25 @@ body:
|
||||
value: |
|
||||
I tried this:
|
||||
|
||||
1. `coyote`
|
||||
1. `loki`
|
||||
|
||||
I expected this to happen:
|
||||
|
||||
Instead, this happened:
|
||||
- type: textarea
|
||||
id: coyote-log
|
||||
id: loki-log
|
||||
attributes:
|
||||
label: Coyote log
|
||||
description: Include the Coyote log file to help diagnose the issue. (`coyote --info` to see the log_path)
|
||||
label: Loki log
|
||||
description: Include the Loki log file to help diagnose the issue. (`loki --info` to see the log_path)
|
||||
value: |
|
||||
| OS | Log file location |
|
||||
| ------- | ----------------------------------------------------- |
|
||||
| Linux | `~/.cache/coyote/coyote.log` |
|
||||
| Mac | `~/Library/Logs/coyote/coyote.log` |
|
||||
| Windows | `C:\Users\<User>\AppData\Local\coyote\coyote.log` |
|
||||
| Linux | `~/.cache/loki/loki.log` |
|
||||
| Mac | `~/Library/Logs/loki/loki.log` |
|
||||
| Windows | `C:\Users\<User>\AppData\Local\loki\loki.log` |
|
||||
|
||||
```
|
||||
please provide a copy of your coyote log file here if possible; you may need to redact some of the lines
|
||||
please provide a copy of your loki log file here if possible; you may need to redact some of the lines
|
||||
```
|
||||
|
||||
- type: input
|
||||
@@ -57,13 +57,13 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: coyote-version
|
||||
id: loki-version
|
||||
attributes:
|
||||
label: Coyote Version
|
||||
label: Loki Version
|
||||
description: >
|
||||
Coyote version (`coyote --version` if using a release, `git describe` if building
|
||||
Loki version (`loki --version` if using a release, `git describe` if building
|
||||
from main).
|
||||
**Make sure that you are using the [latest coyote release](https://github.com/Dark-Alex-17/coyote/releases) or a newer main build**
|
||||
placeholder: "coyote 0.1.0"
|
||||
**Make sure that you are using the [latest loki release](https://github.com/Dark-Alex-17/loki/releases) or a newer main build**
|
||||
placeholder: "loki 0.1.0"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -98,9 +98,9 @@ jobs:
|
||||
# Ignore Act's local artifact dir noise
|
||||
echo artifacts/ >> .git/info/exclude || true
|
||||
|
||||
# Edit the version line right after name="coyote"
|
||||
# Edit the version line right after name="loki"
|
||||
sed -E -i '
|
||||
/^[[:space:]]*name[[:space:]]*=[[:space:]]*"coyote"[[:space:]]*$/ {
|
||||
/^[[:space:]]*name[[:space:]]*=[[:space:]]*"loki"[[:space:]]*$/ {
|
||||
n
|
||||
s|^[[:space:]]*version[[:space:]]*=[[:space:]]*"[^"]*"|version = "'"$VERSION"'"|
|
||||
}
|
||||
@@ -278,7 +278,7 @@ jobs:
|
||||
- name: Verify file
|
||||
shell: bash
|
||||
run: |
|
||||
file target/${{ matrix.target }}/release/coyote
|
||||
file target/${{ matrix.target }}/release/loki
|
||||
|
||||
- name: Test
|
||||
if: matrix.target != 'aarch64-apple-darwin' && matrix.target != 'aarch64-pc-windows-msvc'
|
||||
@@ -382,11 +382,11 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
# Set environment variables
|
||||
macos_sha="$(cat ./artifacts/coyote-x86_64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
macos_sha="$(cat ./artifacts/loki-x86_64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV
|
||||
macos_sha_arm="$(cat ./artifacts/coyote-aarch64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
macos_sha_arm="$(cat ./artifacts/loki-aarch64-apple-darwin.sha256 | awk '{print $1}')"
|
||||
echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV
|
||||
linux_sha="$(cat ./artifacts/coyote-x86_64-unknown-linux-musl.sha256 | awk '{print $1}')"
|
||||
linux_sha="$(cat ./artifacts/loki-x86_64-unknown-linux-musl.sha256 | awk '{print $1}')"
|
||||
echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV
|
||||
release_version="$(cat ./artifacts/release-version)"
|
||||
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
|
||||
@@ -402,23 +402,23 @@ jobs:
|
||||
if: env.ACT != 'true'
|
||||
run: |
|
||||
# run packaging script
|
||||
python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/coyote.rb.template" "./coyote.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }}
|
||||
python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/loki.rb.template" "./loki.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }}
|
||||
|
||||
- name: Push changes to Homebrew tap
|
||||
if: env.ACT != 'true'
|
||||
env:
|
||||
TOKEN: ${{ secrets.COYOTE_GITHUB_TOKEN }}
|
||||
TOKEN: ${{ secrets.LOKI_GITHUB_TOKEN }}
|
||||
run: |
|
||||
# push to Git
|
||||
git config --global user.name "Dark-Alex-17"
|
||||
git config --global user.email "alex.j.tusa@gmail.com"
|
||||
git clone https://Dark-Alex-17:${{ secrets.COYOTE_GITHUB_TOKEN }}@github.com/Dark-Alex-17/homebrew-coyote.git
|
||||
rm homebrew-coyote/Formula/coyote.rb
|
||||
cp coyote.rb homebrew-coyote/Formula
|
||||
cd homebrew-coyote
|
||||
git clone https://Dark-Alex-17:${{ secrets.LOKI_GITHUB_TOKEN }}@github.com/Dark-Alex-17/homebrew-loki.git
|
||||
rm homebrew-loki/Formula/loki.rb
|
||||
cp loki.rb homebrew-loki/Formula
|
||||
cd homebrew-loki
|
||||
git add .
|
||||
git diff-index --quiet HEAD || git commit -am "Update formula for Coyote release ${{ env.RELEASE_VERSION }}"
|
||||
git push https://$TOKEN@github.com/Dark-Alex-17/homebrew-coyote.git
|
||||
git diff-index --quiet HEAD || git commit -am "Update formula for Loki release ${{ env.RELEASE_VERSION }}"
|
||||
git push https://$TOKEN@github.com/Dark-Alex-17/homebrew-loki.git
|
||||
|
||||
publish-crate:
|
||||
needs: publish-github-release
|
||||
|
||||
+1
-1
@@ -3,5 +3,5 @@
|
||||
/.env
|
||||
!cli/**
|
||||
.idea/
|
||||
/coyote.iml
|
||||
/loki.iml
|
||||
/.idea/
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"type":"rust","build":"cargo build","test":"cargo test","check":"cargo check","_detected_by":"heuristic","_cached_at":"2026-04-13T13:36:33-06:00"}
|
||||
+4
-115
@@ -1,114 +1,3 @@
|
||||
## v0.5.0 (2026-05-27)
|
||||
|
||||
### Feat
|
||||
|
||||
- rename Loki to Coyote
|
||||
|
||||
### Fix
|
||||
|
||||
- bash-based user interactions in agents accidentally regressed in graph implementation
|
||||
- Claude function calling in agent contexts
|
||||
- Claude code rate limit error per new Claude changes
|
||||
|
||||
## v0.4.0 (2026-05-23)
|
||||
|
||||
### Feat
|
||||
|
||||
- LLM node failures propgate up
|
||||
- Added .install remote tab completions to the REPL
|
||||
- feature complete install remote with category selection
|
||||
- Support to interactively add secrets to Coyote that are missing from MCP configs when merging
|
||||
- Added MCP config merging support for remote asset installations
|
||||
- install remote now writes files to disk
|
||||
- Created basic install_remote functions
|
||||
- Created a more comprehensive and immediately useful default config for first runs
|
||||
- Created an example graph-based agent called deep-research
|
||||
- Improved coder agent that is now a graph-based agent
|
||||
- Removed indicatif spinners. The UX just won't stop clobbering for parallel graph nodes
|
||||
- Added agent variables support for graph agents and improved script executor to use the same environment variables as normal agent tool calling for further flexibility
|
||||
- Improved UX with colored spinners for parallel graph agents and no clobbering outputs for sub-agents
|
||||
- created new graph-based deep-research agent
|
||||
- improved UX for parallel graph execution
|
||||
- added branch progress tracker for better visualization of parallel graph super-steps
|
||||
- Removed the jira-helper agent and replaced it with the atlassian role
|
||||
- created the RenderMode enum to suppress stdout streaming during parallel graph super-steps
|
||||
- Full support for map node types
|
||||
- implemented the frontier-based scheduling for the graph executor with simplified state management (gotta love .clone)
|
||||
- validation support for parallel graph execution; restricted map nodes to only run for nodes without next targets and not supporting chained map nodes
|
||||
- created the staging area for state merges per super-step and created the built-in reducers (and their application) for the state merge phase of a super step
|
||||
- scaffolding work for fan-out nodes for parallel branch execution support and stubbed out Map node types
|
||||
- Coyote can now update itself via .update and --update commands
|
||||
- added a .edit command for editing the MCP configuration file
|
||||
- Created a new .install command to install bundled assets on-demand
|
||||
- migrated llm node validation to graph loading time instead of graph runtime
|
||||
- ripped out user input timeout scaffolding for approval and input node types; implementation can't be done cleanly
|
||||
- added additional support for all RAG-configuration fields in RAG nodes
|
||||
- initial support for RAG nodes in the graph execution system
|
||||
- implemented structured logging for graph execution
|
||||
- merged normal agent config and graph agent configs into one file (either/or)
|
||||
- added structured-output extraction for llm and agent nodes
|
||||
- created full llm node runtime implementation
|
||||
- scaffolded together the initial llm node type and its executor
|
||||
- wired together graph execution and agent graph dispatch
|
||||
- implemented support for the graph executor
|
||||
- created the approval node executor and the input node executor for user interaction
|
||||
- Added initial support for native Coyote agent nodes in the graph-based agent system
|
||||
- Added direct script invocation support for graph-based agents
|
||||
- Added graph validation
|
||||
- Implemented state management for agent graphs
|
||||
- initial agent graph scaffolding
|
||||
- add auto-continue support to all contexts
|
||||
- dynamic tab completions now show the sessions for a given agent instead of only listing global sessions
|
||||
- legacy SSE support for MCP server configurations
|
||||
- support http/sse transport types for MCP server configurations so it fully supports claude desktop-style MCP configs
|
||||
- 99% complete migration to new state structs to get away from God-Config struct; i.e. AppConfig, AppState, and RequestContext
|
||||
- Automatic runtime customization using shebangs
|
||||
- Created a demo TypeScript tool and a get_current_weather function in TypeScript
|
||||
- Updated the Python demo tool to show all possible parameter types and variations
|
||||
- Added TypeScript tool support using the refactored common ScriptedLanguage trait
|
||||
|
||||
### Fix
|
||||
|
||||
- Generified the functions usage of script detection for an executable bit on unix systems
|
||||
- merge required claude code system prompt into instructions
|
||||
- updated argc argument passing in run-tool and run-agent scripts
|
||||
- Added additional graph validation for parallel reads and writes with dependencies between nodes states
|
||||
- bug in next_single method and improved outcome handling for LLM node execution
|
||||
- inline RAG bug when globbing files by extension without subdirectory globbing
|
||||
- update the estimate_token_length function to use the standard word count method
|
||||
- removed unnecessary regenerate logic for sessions and use the same logic for all contexts; prevents a panic on empty message list
|
||||
- error when users try to start a session on a graph agent
|
||||
- added on_other field for approval nodes so users can specify an alternative free-text target when none of the options match what they want
|
||||
- accidentally added back in full agent tools on LLM nodes
|
||||
- Improve the coder agent's usage of tools
|
||||
- make the agent__collect escalation-aware so it doesn't freeze on sub-agent escalations
|
||||
- check for an existing session before starting up MCP servers when switching to a role
|
||||
- do not switch to agent if a session is active.
|
||||
- Do not append todo instructions when function calling is disabled
|
||||
- a bug in the dynamic completions because the crate name is coyote-ai but the binary is named coyote
|
||||
- bug found by copilot that would create a lock on the PollSender for sse-based MCP servers
|
||||
- Accidental shadow of temp_file function for Windows function calling
|
||||
- upgraded to newer rmcp version to get native-tls support
|
||||
- RagCache was not being used for agent and sub-agent instantiation
|
||||
- TypeScript function args were being passed as objects rather than direct parameters
|
||||
- Added in forgotten wrapper scripts for TypeScript tools
|
||||
- don't shadow variables in binary path handling for Windows
|
||||
- Tool call improvements for Windows systems
|
||||
|
||||
### Refactor
|
||||
|
||||
- migrated llm nodes to use Roles to simplify instructions handling and to function like inline roles
|
||||
- migrated the next_node and apply_state_updates logic for LLM nodes into the LlmExecutor
|
||||
- fully complete state re-architecting
|
||||
- Fully ripped out the god Config struct
|
||||
- Deprecated old Config struct initialization logic
|
||||
- migrate functions and MCP servers to AppConfig
|
||||
- Migrate the vault/bare_init logic
|
||||
- created a single install_builtins free function to remove from Config::init
|
||||
- partial migration to init in AppConfig
|
||||
- Extracted common Python parser logic into a common.rs module
|
||||
- python tools now use tree-sitter queries instead of AST
|
||||
|
||||
## v0.3.0 (2026-04-02)
|
||||
|
||||
### Feat
|
||||
@@ -132,7 +21,7 @@
|
||||
- Created a CodeRabbit-style code-reviewer agent
|
||||
- Added configuration option in agents to indicate the timeout for user input before proceeding (defaults to 5 minutes)
|
||||
- Added support for sub-agents to escalate user interaction requests from any depth to the parent agents for user interactions
|
||||
- built-in user interaction tools to remove the need for the list/confirm/etc prompts in prompt tools and to enhance user interactions in Coyote
|
||||
- built-in user interaction tools to remove the need for the list/confirm/etc prompts in prompt tools and to enhance user interactions in Loki
|
||||
- Experimental update to sisyphus to use the new parallel agent spawning system
|
||||
- Added an agent configuration property that allows auto-injecting sub-agent spawning instructions (when using the built-in sub-agent spawning system)
|
||||
- Auto-dispatch support of sub-agents and support for the teammate pattern between subagents
|
||||
@@ -186,7 +75,7 @@
|
||||
|
||||
- Simplified sisyphus prompt to improve functionality
|
||||
- Supported the injection of RAG sources into the prompt, not just via the `.sources rag` command in the REPL so models can directly reference the documents that supported their responses
|
||||
- Created the Sisyphus agent to make Coyote function like Claude Code, Gemini, Codex, etc.
|
||||
- Created the Sisyphus agent to make Loki function like Claude Code, Gemini, Codex, etc.
|
||||
- Created the Oracle agent to handle high-level architectural decisions and design questions about a given codebase
|
||||
- Updated the coder agent to be much more task-focused and to be delegated to by Sisyphus
|
||||
- Created the explore agent for exploring codebases to help answer questions
|
||||
@@ -246,8 +135,8 @@
|
||||
- Support for secret injection into the global config file (API keys, for example)
|
||||
- Improved MCP handling toggle handling
|
||||
- Secret injection into the MCP configuration
|
||||
- added REPL support for interacting with the Coyote vault
|
||||
- Integrated gman with Coyote to create a vault and added flags to configure the Coyote vault
|
||||
- added REPL support for interacting with the Loki vault
|
||||
- Integrated gman with Loki to create a vault and added flags to configure the Loki vault
|
||||
- Added a default session to the jira helper to make interaction more natural
|
||||
- Created the repo-analyzer role
|
||||
- Created the coder and sql agents
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
Contributors are very welcome! **No contribution is too small and all contributions are valued.**
|
||||
|
||||
## Rust
|
||||
You'll need to have the stable Rust toolchain installed in order to develop Coyote.
|
||||
You'll need to have the stable Rust toolchain installed in order to develop Loki.
|
||||
|
||||
The Rust toolchain (stable) can be installed via rustup using the following command:
|
||||
|
||||
@@ -84,5 +84,5 @@ Claude, etc.) is not permitted unless explicitly disclosed and approved.
|
||||
Submissions must certify that the contributor understands and can maintain the code they submit.
|
||||
|
||||
## Questions? Reach out to me!
|
||||
If you encounter any questions while developing Coyote, please don't hesitate to reach out to me at
|
||||
If you encounter any questions while developing Loki, please don't hesitate to reach out to me at
|
||||
alex.j.tusa@gmail.com. I'm happy to help contributors in any way I can, regardless of if they're new or experienced!
|
||||
|
||||
+6
-6
@@ -1,19 +1,19 @@
|
||||
# Credits
|
||||
|
||||
## AIChat
|
||||
Coyote originally started as a fork of the fantastic
|
||||
Loki originally started as a fork of the fantastic
|
||||
[AIChat CLI](https://github.com/sigoden/aichat). The initial goal was simply
|
||||
to fix a bug in how MCP servers worked with AIChat, allowing different MCP
|
||||
servers to be specified per agent. Since then, Coyote has evolved far beyond
|
||||
servers to be specified per agent. Since then, Loki has evolved far beyond
|
||||
its original scope and grown into a passion project with a life of its own.
|
||||
|
||||
Today, Coyote includes first-class MCP server support (for both local and remote
|
||||
Today, Loki includes first-class MCP server support (for both local and remote
|
||||
servers), a built-in vault for interpolating secrets in configuration files,
|
||||
built-in agents and macros, dynamic tab completions, integrated custom
|
||||
functions (no external `argc` dependency), improved documentation, and much
|
||||
more with many more ideas planned for the future.
|
||||
|
||||
Coyote is now developed and maintained as an independent project. Full credit
|
||||
Loki is now developed and maintained as an independent project. Full credit
|
||||
for the original foundation goes to the developers of the wonderful
|
||||
AIChat project.
|
||||
|
||||
@@ -21,10 +21,10 @@ This project is not affiliated with or endorsed by the AIChat maintainers.
|
||||
|
||||
## AIChat
|
||||
|
||||
Coyote originally began as a fork of [AIChat CLI](https://github.com/sigoden/aichat),
|
||||
Loki originally began as a fork of [AIChat CLI](https://github.com/sigoden/aichat),
|
||||
created and maintained by the AIChat contributors.
|
||||
|
||||
While Coyote has since diverged significantly and is now developed as an
|
||||
While Loki has since diverged significantly and is now developed as an
|
||||
independent project, its early foundation and inspiration came from the
|
||||
AIChat project.
|
||||
|
||||
|
||||
Generated
+138
-138
@@ -298,7 +298,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"hex",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"sha1",
|
||||
"time",
|
||||
"tokio",
|
||||
@@ -371,7 +371,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"bytes-utils",
|
||||
"fastrand",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
@@ -398,7 +398,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -422,7 +422,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -446,7 +446,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -471,7 +471,7 @@ dependencies = [
|
||||
"aws-types",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"regex-lite",
|
||||
"tracing",
|
||||
]
|
||||
@@ -491,7 +491,7 @@ dependencies = [
|
||||
"hex",
|
||||
"hmac 0.13.0",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"percent-encoding",
|
||||
"sha2 0.11.0",
|
||||
"time",
|
||||
@@ -532,7 +532,7 @@ dependencies = [
|
||||
"bytes-utils",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"percent-encoding",
|
||||
@@ -553,10 +553,10 @@ dependencies = [
|
||||
"h2 0.3.27",
|
||||
"h2 0.4.14",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.32",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-rustls 0.24.2",
|
||||
"hyper-rustls 0.27.9",
|
||||
"hyper-util",
|
||||
@@ -617,7 +617,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"fastrand",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 0.4.6",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
@@ -638,7 +638,7 @@ dependencies = [
|
||||
"aws-smithy-types",
|
||||
"bytes",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -664,7 +664,7 @@ checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5"
|
||||
dependencies = [
|
||||
"aws-smithy-runtime-api",
|
||||
"aws-smithy-types",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -678,7 +678,7 @@ dependencies = [
|
||||
"bytes-utils",
|
||||
"futures-core",
|
||||
"http 0.2.12",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 0.4.6",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
@@ -726,7 +726,7 @@ dependencies = [
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"itoa",
|
||||
@@ -750,7 +750,7 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
@@ -1396,83 +1396,6 @@ version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "coyote-ai"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"ansi_colours",
|
||||
"anyhow",
|
||||
"arboard",
|
||||
"argc",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"aws-smithy-eventstream",
|
||||
"base64",
|
||||
"bincode 2.0.1",
|
||||
"bitflags",
|
||||
"bm25",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"colored",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"duct",
|
||||
"dunce",
|
||||
"eventsource-stream",
|
||||
"fancy-regex",
|
||||
"futures-util",
|
||||
"fuzzy-matcher",
|
||||
"gman",
|
||||
"hmac 0.12.1",
|
||||
"hnsw_rs",
|
||||
"html_to_markdown",
|
||||
"http 1.4.1",
|
||||
"indexmap 2.14.0",
|
||||
"indoc",
|
||||
"inquire",
|
||||
"is-terminal",
|
||||
"json-patch",
|
||||
"log",
|
||||
"log4rs",
|
||||
"nu-ansi-term",
|
||||
"num_cpus",
|
||||
"open",
|
||||
"os_info",
|
||||
"parking_lot",
|
||||
"path-absolutize",
|
||||
"pretty_assertions",
|
||||
"rand 0.10.1",
|
||||
"reedline",
|
||||
"reqwest 0.13.4",
|
||||
"rmcp",
|
||||
"rust-embed",
|
||||
"scraper",
|
||||
"self_update",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"serial_test",
|
||||
"sha2 0.10.9",
|
||||
"shell-words",
|
||||
"strum_macros",
|
||||
"syntect",
|
||||
"sys-locale",
|
||||
"terminal-colorsaurus",
|
||||
"textwrap",
|
||||
"tokio",
|
||||
"tree-sitter",
|
||||
"tree-sitter-python",
|
||||
"tree-sitter-typescript",
|
||||
"unicode-width",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"uuid",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpu-time"
|
||||
version = "1.0.0"
|
||||
@@ -1872,9 +1795,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "displaydoc"
|
||||
version = "0.2.6"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f"
|
||||
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2333,7 +2256,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"chrono",
|
||||
"futures",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"jsonwebtoken",
|
||||
"once_cell",
|
||||
"prost",
|
||||
@@ -2502,7 +2425,7 @@ dependencies = [
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"indexmap 2.14.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -2654,9 +2577,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.4.1"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0"
|
||||
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"itoa",
|
||||
@@ -2680,7 +2603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2691,7 +2614,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"pin-project-lite",
|
||||
]
|
||||
@@ -2765,16 +2688,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.10.0"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb92f162bf56536459fc83c79b974bb12837acfed43d6bc370a7916d0ae15ecc"
|
||||
checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"h2 0.4.14",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
@@ -2806,8 +2729,8 @@ version = "0.27.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
|
||||
dependencies = [
|
||||
"http 1.4.1",
|
||||
"hyper 1.10.0",
|
||||
"http 1.4.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-util",
|
||||
"rustls 0.23.40",
|
||||
"rustls-native-certs",
|
||||
@@ -2822,7 +2745,7 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
|
||||
dependencies = [
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-util",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
@@ -2837,7 +2760,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
@@ -2855,9 +2778,9 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"ipnet",
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
@@ -3152,9 +3075,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.27"
|
||||
version = "0.2.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "392c70591e8749fe235ddaf513e6f58b26bce3dcc16524cecc8936f75afa161e"
|
||||
checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"log",
|
||||
@@ -3165,9 +3088,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "jiff-static"
|
||||
version = "0.2.27"
|
||||
version = "0.2.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b605b0c050d845fc355bb11eb3f9a8deddc218ea60c76e61aa1f2adfb2c96a"
|
||||
checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3314,9 +3237,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.17"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3"
|
||||
checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@@ -3350,9 +3273,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.30"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
@@ -3392,6 +3315,83 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "loki-ai"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"ansi_colours",
|
||||
"anyhow",
|
||||
"arboard",
|
||||
"argc",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"aws-smithy-eventstream",
|
||||
"base64",
|
||||
"bincode 2.0.1",
|
||||
"bitflags",
|
||||
"bm25",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"colored",
|
||||
"crossterm",
|
||||
"dirs",
|
||||
"duct",
|
||||
"dunce",
|
||||
"eventsource-stream",
|
||||
"fancy-regex",
|
||||
"futures-util",
|
||||
"fuzzy-matcher",
|
||||
"gman",
|
||||
"hmac 0.12.1",
|
||||
"hnsw_rs",
|
||||
"html_to_markdown",
|
||||
"http 1.4.0",
|
||||
"indexmap 2.14.0",
|
||||
"indoc",
|
||||
"inquire",
|
||||
"is-terminal",
|
||||
"json-patch",
|
||||
"log",
|
||||
"log4rs",
|
||||
"nu-ansi-term",
|
||||
"num_cpus",
|
||||
"open",
|
||||
"os_info",
|
||||
"parking_lot",
|
||||
"path-absolutize",
|
||||
"pretty_assertions",
|
||||
"rand 0.10.1",
|
||||
"reedline",
|
||||
"reqwest 0.13.3",
|
||||
"rmcp",
|
||||
"rust-embed",
|
||||
"scraper",
|
||||
"self_update",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"serial_test",
|
||||
"sha2 0.10.9",
|
||||
"shell-words",
|
||||
"strum_macros",
|
||||
"syntect",
|
||||
"sys-locale",
|
||||
"terminal-colorsaurus",
|
||||
"textwrap",
|
||||
"tokio",
|
||||
"tree-sitter",
|
||||
"tree-sitter-python",
|
||||
"tree-sitter-typescript",
|
||||
"unicode-width",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"uuid",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
version = "0.1.2"
|
||||
@@ -3472,9 +3472,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.1"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
@@ -4664,10 +4664,10 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-rustls 0.27.9",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
@@ -4700,9 +4700,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.13.4"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
|
||||
checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -4710,10 +4710,10 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.4.14",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-rustls 0.27.9",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
@@ -4778,11 +4778,11 @@ dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
"futures",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"pastey",
|
||||
"pin-project-lite",
|
||||
"process-wrap",
|
||||
"reqwest 0.13.4",
|
||||
"reqwest 0.13.3",
|
||||
"rmcp-macros",
|
||||
"schemars 1.2.1",
|
||||
"serde",
|
||||
@@ -5207,12 +5207,12 @@ checksum = "2e79722b5a505d4ddc77527455a97244e9e8c4c07533ff44cf4421cce7bb6d17"
|
||||
dependencies = [
|
||||
"either",
|
||||
"flate2",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"indicatif",
|
||||
"log",
|
||||
"quick-xml 0.38.4",
|
||||
"regex",
|
||||
"reqwest 0.13.4",
|
||||
"reqwest 0.13.3",
|
||||
"self-replace",
|
||||
"semver",
|
||||
"serde",
|
||||
@@ -6126,10 +6126,10 @@ dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"h2 0.4.14",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"hyper 1.10.0",
|
||||
"hyper 1.9.0",
|
||||
"hyper-timeout",
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
@@ -6187,7 +6187,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"http-body 1.0.1",
|
||||
"http-body-util",
|
||||
"pin-project-lite",
|
||||
@@ -6473,7 +6473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"http 1.4.1",
|
||||
"http 1.4.0",
|
||||
"httparse",
|
||||
"log",
|
||||
]
|
||||
@@ -7440,18 +7440,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.49"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b"
|
||||
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.49"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e"
|
||||
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
[package]
|
||||
name = "coyote-ai"
|
||||
version = "0.5.0"
|
||||
name = "loki-ai"
|
||||
version = "0.3.0"
|
||||
edition = "2024"
|
||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||
description = "An all-in-one, batteries included LLM CLI Tool"
|
||||
keywords = ["chatgpt", "llm", "cli", "ai", "repl"]
|
||||
homepage = "https://github.com/Dark-Alex-17/coyote"
|
||||
repository = "https://github.com/Dark-Alex-17/coyote"
|
||||
homepage = "https://github.com/Dark-Alex-17/loki"
|
||||
repository = "https://github.com/Dark-Alex-17/loki"
|
||||
categories = ["command-line-utilities"]
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
@@ -138,7 +138,7 @@ pretty_assertions = "1.4.0"
|
||||
serial_test = "3"
|
||||
|
||||
[[bin]]
|
||||
name = "coyote"
|
||||
name = "loki"
|
||||
path = "src/main.rs"
|
||||
|
||||
[profile.release]
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
# Coyote: All-in-one, batteries-included LLM CLI Tool
|
||||
# Loki: All-in-one, batteries-included LLM CLI Tool
|
||||
|
||||

|
||||
[](https://crates.io/crates/coyote-ai)
|
||||

|
||||

|
||||
[](https://github.com/Dark-Alex-17/coyote/releases)
|
||||

|
||||
[](https://crates.io/crates/loki-ai)
|
||||

|
||||

|
||||
[](https://github.com/Dark-Alex-17/loki/releases)
|
||||
|
||||
Coyote is an all-in-one, batteries-included, LLM CLI tool featuring Shell Assistant, CLI & REPL Mode, RAG, AI Tools &
|
||||
Loki is an all-in-one, batteries-included, LLM CLI tool featuring Shell Assistant, CLI & REPL Mode, RAG, AI Tools &
|
||||
Agents, and More.
|
||||
|
||||
It is designed to include a number of useful agents, roles, macros, and more so users can get up and running with Coyote
|
||||
It is designed to include a number of useful agents, roles, macros, and more so users can get up and running with Loki
|
||||
in as little time as possible. You can also install entire bundles of agents, roles, macros, tools, and MCP servers from
|
||||
any git repository. See [Sharing Configurations](https://github.com/Dark-Alex-17/coyote/wiki/Sharing-Configurations) for more information.
|
||||
any git repository — see [Sharing Configurations](#sharing-configurations).
|
||||
|
||||

|
||||

|
||||
|
||||
Coming from [AIChat](https://github.com/sigoden/aichat)? Follow the [migration guide](https://github.com/Dark-Alex-17/coyote/wiki/AIChat-Migration) to get started.
|
||||
Coming from [AIChat](https://github.com/sigoden/aichat)? Follow the [migration guide](https://github.com/Dark-Alex-17/loki/wiki/AIChat-Migration) to get started.
|
||||
|
||||
## Quick Links
|
||||
* [AIChat Migration Guide](https://github.com/Dark-Alex-17/coyote/wiki/AIChat-Migration): Coming from AIChat? Follow the migration guide to get started.
|
||||
* [Installation](#install): Install Coyote
|
||||
* [Getting Started](#getting-started): Get started with Coyote by doing first-run setup steps.
|
||||
* [Sharing Configurations](https://github.com/Dark-Alex-17/coyote/wiki/Sharing-Configurations): Install bundles of agents, roles, macros, tools, and MCP servers from any git repo, and share your own.
|
||||
* [REPL](https://github.com/Dark-Alex-17/coyote/wiki/REPL): Interactive Read-Eval-Print Loop for conversational interactions with LLMs and Coyote.
|
||||
* [Custom REPL Prompt](https://github.com/Dark-Alex-17/coyote/wiki/REPL-Prompt): Customize the REPL prompt to provide useful contextual information.
|
||||
* [Vault](https://github.com/Dark-Alex-17/coyote/wiki/Vault): Securely store and manage sensitive information such as API keys and credentials.
|
||||
* [Shell Integrations](https://github.com/Dark-Alex-17/coyote/wiki/Shell-Integrations): Seamlessly integrate Coyote with your shell environment for enhanced command-line assistance.
|
||||
* [Function Calling](https://github.com/Dark-Alex-17/coyote/wiki/Tools): Leverage function calling capabilities to extend Coyote's functionality with custom tools
|
||||
* [Creating Custom Tools](https://github.com/Dark-Alex-17/coyote/wiki/Custom-Tools): You can create your own custom tools to enhance Coyote's capabilities.
|
||||
* [Create Custom Python Tools](https://github.com/Dark-Alex-17/coyote/wiki/Custom-Tools#custom-python-based-tools)
|
||||
* [Create Custom TypeScript Tools](https://github.com/Dark-Alex-17/coyote/wiki/Custom-Tools#custom-typescript-based-tools)
|
||||
* [Create Custom Bash Tools](https://github.com/Dark-Alex-17/coyote/wiki/Custom-Bash-Tools)
|
||||
* [Bash Prompt Utilities](https://github.com/Dark-Alex-17/coyote/wiki/Bash-Prompt-Helpers)
|
||||
* [First-Class MCP Server Support](https://github.com/Dark-Alex-17/coyote/wiki/MCP-Servers): Easily connect and interact with MCP servers for advanced functionality.
|
||||
* [Macros](https://github.com/Dark-Alex-17/coyote/wiki/Macros): Automate repetitive tasks and workflows with Coyote "scripts" (macros).
|
||||
* [RAG](https://github.com/Dark-Alex-17/coyote/wiki/RAG): Retrieval-Augmented Generation for enhanced information retrieval and generation.
|
||||
* [Sessions](https://github.com/Dark-Alex-17/coyote/wiki/Sessions): Manage and persist conversational contexts and settings across multiple interactions.
|
||||
* [Roles](https://github.com/Dark-Alex-17/coyote/wiki/Roles): Customize model behavior for specific tasks or domains.
|
||||
* [Agents](https://github.com/Dark-Alex-17/coyote/wiki/Agents): Leverage AI agents to perform complex tasks and workflows, including sub-agent spawning, teammate messaging, and user interaction tools.
|
||||
* [Graph Agents](https://github.com/Dark-Alex-17/coyote/wiki/Graph-Agents): Define an agent as a declarative, YAML-driven workflow. A directed graph of typed nodes (LLM calls, scripts, approvals, user input, RAG retrieval, sub-agent spawns).
|
||||
* [Todo System](https://github.com/Dark-Alex-17/coyote/wiki/TODO-System): Built-in task tracking for improved LLM reliability with smaller models.
|
||||
* [Environment Variables](https://github.com/Dark-Alex-17/coyote/wiki/Environment-Variables): Override and customize your Coyote configuration at runtime with environment variables.
|
||||
* [Client Configurations](https://github.com/Dark-Alex-17/coyote/wiki/Clients): Configuration instructions for various LLM providers.
|
||||
* [Authentication (API Key & OAuth)](https://github.com/Dark-Alex-17/coyote/wiki/Clients#authentication): Authenticate with API keys or OAuth for subscription-based access.
|
||||
* [Patching API Requests](https://github.com/Dark-Alex-17/coyote/wiki/Patches): Learn how to patch API requests for advanced customization.
|
||||
* [Custom Themes](https://github.com/Dark-Alex-17/coyote/wiki/Themes): Change the look and feel of Coyote to your preferences with custom themes.
|
||||
* [History](#history): A history of how Coyote came to be.
|
||||
* [AIChat Migration Guide](https://github.com/Dark-Alex-17/loki/wiki/AIChat-Migration): Coming from AIChat? Follow the migration guide to get started.
|
||||
* [Installation](#install): Install Loki
|
||||
* [Getting Started](#getting-started): Get started with Loki by doing first-run setup steps.
|
||||
* [Sharing Configurations](https://github.com/Dark-Alex-17/loki/wiki/Sharing-Configurations): Install bundles of agents, roles, macros, tools, and MCP servers from any git repo, and share your own.
|
||||
* [REPL](https://github.com/Dark-Alex-17/loki/wiki/REPL): Interactive Read-Eval-Print Loop for conversational interactions with LLMs and Loki.
|
||||
* [Custom REPL Prompt](https://github.com/Dark-Alex-17/loki/wiki/REPL-Prompt): Customize the REPL prompt to provide useful contextual information.
|
||||
* [Vault](https://github.com/Dark-Alex-17/loki/wiki/Vault): Securely store and manage sensitive information such as API keys and credentials.
|
||||
* [Shell Integrations](https://github.com/Dark-Alex-17/loki/wiki/Shell-Integrations): Seamlessly integrate Loki with your shell environment for enhanced command-line assistance.
|
||||
* [Function Calling](https://github.com/Dark-Alex-17/loki/wiki/Tools): Leverage function calling capabilities to extend Loki's functionality with custom tools
|
||||
* [Creating Custom Tools](https://github.com/Dark-Alex-17/loki/wiki/Custom-Tools): You can create your own custom tools to enhance Loki's capabilities.
|
||||
* [Create Custom Python Tools](https://github.com/Dark-Alex-17/loki/wiki/Custom-Tools#custom-python-based-tools)
|
||||
* [Create Custom TypeScript Tools](https://github.com/Dark-Alex-17/loki/wiki/Custom-Tools#custom-typescript-based-tools)
|
||||
* [Create Custom Bash Tools](https://github.com/Dark-Alex-17/loki/wiki/Custom-Bash-Tools)
|
||||
* [Bash Prompt Utilities](https://github.com/Dark-Alex-17/loki/wiki/Bash-Prompt-Helpers)
|
||||
* [First-Class MCP Server Support](https://github.com/Dark-Alex-17/loki/wiki/MCP-Servers): Easily connect and interact with MCP servers for advanced functionality.
|
||||
* [Macros](https://github.com/Dark-Alex-17/loki/wiki/Macros): Automate repetitive tasks and workflows with Loki "scripts" (macros).
|
||||
* [RAG](https://github.com/Dark-Alex-17/loki/wiki/RAG): Retrieval-Augmented Generation for enhanced information retrieval and generation.
|
||||
* [Sessions](https://github.com/Dark-Alex-17/loki/wiki/Sessions): Manage and persist conversational contexts and settings across multiple interactions.
|
||||
* [Roles](https://github.com/Dark-Alex-17/loki/wiki/Roles): Customize model behavior for specific tasks or domains.
|
||||
* [Agents](https://github.com/Dark-Alex-17/loki/wiki/Agents): Leverage AI agents to perform complex tasks and workflows, including sub-agent spawning, teammate messaging, and user interaction tools.
|
||||
* [Graph Agents](https://github.com/Dark-Alex-17/loki/wiki/Graph-Agents): Define an agent as a declarative, YAML-driven workflow. A directed graph of typed nodes (LLM calls, scripts, approvals, user input, RAG retrieval, sub-agent spawns).
|
||||
* [Todo System](https://github.com/Dark-Alex-17/loki/wiki/TODO-System): Built-in task tracking for improved LLM reliability with smaller models.
|
||||
* [Environment Variables](https://github.com/Dark-Alex-17/loki/wiki/Environment-Variables): Override and customize your Loki configuration at runtime with environment variables.
|
||||
* [Client Configurations](https://github.com/Dark-Alex-17/loki/wiki/Clients): Configuration instructions for various LLM providers.
|
||||
* [Authentication (API Key & OAuth)](https://github.com/Dark-Alex-17/loki/wiki/Clients#authentication): Authenticate with API keys or OAuth for subscription-based access.
|
||||
* [Patching API Requests](https://github.com/Dark-Alex-17/loki/wiki/Patches): Learn how to patch API requests for advanced customization.
|
||||
* [Custom Themes](https://github.com/Dark-Alex-17/loki/wiki/Themes): Change the look and feel of Loki to your preferences with custom themes.
|
||||
* [History](#history): A history of how Loki came to be.
|
||||
|
||||
## Prerequisites
|
||||
Coyote requires the following tools to be installed on your system:
|
||||
Loki requires the following tools to be installed on your system:
|
||||
* [jq](https://github.com/jqlang/jq)
|
||||
* `brew install jq`
|
||||
* [usql](https://github.com/xo/usql) (For the `sql` agent)
|
||||
@@ -57,57 +57,57 @@ Coyote requires the following tools to be installed on your system:
|
||||
* [uv](https://docs.astral.sh/uv/getting-started/installation/)
|
||||
* `curl -LsSf https://astral.sh/uv/install.sh | sh`
|
||||
|
||||
These tools are used to provide various functionalities within Coyote, such as document processing, JSON manipulation,
|
||||
These tools are used to provide various functionalities within Loki, such as document processing, JSON manipulation,
|
||||
etc., and they are used within agents and tools.
|
||||
|
||||
## Install
|
||||
|
||||
### Cargo
|
||||
If you have Cargo installed, then you can install `coyote` from Crates.io:
|
||||
If you have Cargo installed, then you can install `loki` from Crates.io:
|
||||
|
||||
```shell
|
||||
cargo install coyote-ai # Binary name is `coyote`
|
||||
cargo install loki-ai # Binary name is `loki`
|
||||
|
||||
# If you encounter issues installing, try installing with '--locked'
|
||||
cargo install --locked coyote-ai
|
||||
cargo install --locked loki-ai
|
||||
```
|
||||
|
||||
### Homebrew (Mac/Linux)
|
||||
To install Coyote from Homebrew, install the `coyote` tap. Then you'll be able to install `coyote`:
|
||||
To install Loki from Homebrew, install the `loki` tap. Then you'll be able to install `loki`:
|
||||
|
||||
```shell
|
||||
brew tap Dark-Alex-17/coyote
|
||||
brew install coyote
|
||||
brew tap Dark-Alex-17/loki
|
||||
brew install loki
|
||||
|
||||
# If you need to be more specific, use:
|
||||
brew install Dark-Alex-17/coyote/coyote
|
||||
brew install Dark-Alex-17/loki/loki
|
||||
```
|
||||
|
||||
To upgrade `coyote` using Homebrew:
|
||||
To upgrade `loki` using Homebrew:
|
||||
|
||||
```shell
|
||||
brew upgrade coyote
|
||||
brew upgrade loki
|
||||
```
|
||||
|
||||
### Scripts
|
||||
#### Linux/MacOS (`bash`)
|
||||
You can use the following command to run a bash script that downloads and installs the latest version of `coyote` for your
|
||||
You can use the following command to run a bash script that downloads and installs the latest version of `loki` for your
|
||||
OS (Linux/MacOS) and architecture (x86_64/arm64):
|
||||
|
||||
```shell
|
||||
curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/install_coyote.sh | bash
|
||||
curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/loki/main/install_loki.sh | bash
|
||||
```
|
||||
|
||||
#### Windows/Linux/MacOS (`PowerShell`)
|
||||
You can use the following command to run a PowerShell script that downloads and installs the latest version of `coyote`
|
||||
You can use the following command to run a PowerShell script that downloads and installs the latest version of `loki`
|
||||
for your OS (Windows/Linux/MacOS) and architecture (x86_64/arm64):
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/scripts/install_coyote.ps1 | iex"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/Dark-Alex-17/loki/main/scripts/install_loki.ps1 | iex"
|
||||
```
|
||||
|
||||
### Manual
|
||||
Binaries are available on the [releases](https://github.com/Dark-Alex-17/coyote/releases) page for the following platforms:
|
||||
Binaries are available on the [releases](https://github.com/Dark-Alex-17/loki/releases) page for the following platforms:
|
||||
|
||||
| Platform | Architecture(s) |
|
||||
|----------------|-----------------|
|
||||
@@ -118,103 +118,102 @@ Binaries are available on the [releases](https://github.com/Dark-Alex-17/coyote/
|
||||
#### Windows Instructions
|
||||
To use a binary from the releases page on Windows, do the following:
|
||||
|
||||
1. Download the latest [binary](https://github.com/Dark-Alex-17/coyote/releases) for your OS.
|
||||
1. Download the latest [binary](https://github.com/Dark-Alex-17/loki/releases) for your OS.
|
||||
2. Use 7-Zip or TarTool to unpack the Tar file.
|
||||
3. Run the executable `coyote.exe`!
|
||||
3. Run the executable `loki.exe`!
|
||||
|
||||
#### Linux/MacOS Instructions
|
||||
To use a binary from the releases page on Linux/MacOS, do the following:
|
||||
|
||||
1. Download the latest [binary](https://github.com/Dark-Alex-17/coyote/releases) for your OS.
|
||||
1. Download the latest [binary](https://github.com/Dark-Alex-17/loki/releases) for your OS.
|
||||
2. `cd` to the directory where you downloaded the binary.
|
||||
3. Extract the binary with `tar -C /usr/local/bin -xzf coyote-<arch>.tar.gz` (Note: This may require `sudo`)
|
||||
4. Now you can run `coyote`!
|
||||
3. Extract the binary with `tar -C /usr/local/bin -xzf loki-<arch>.tar.gz` (Note: This may require `sudo`)
|
||||
4. Now you can run `loki`!
|
||||
|
||||
## Updating
|
||||
Coyote can update itself in place to the latest GitHub release. Run `coyote --update`
|
||||
for the newest release, or `coyote --update v0.4.0` for a specific version:
|
||||
Loki can update itself in place to the latest GitHub release. Run `loki --update`
|
||||
for the newest release, or `loki --update v0.4.0` for a specific version:
|
||||
|
||||
```shell
|
||||
coyote --update
|
||||
coyote --update v0.4.0
|
||||
loki --update
|
||||
loki --update v0.4.0
|
||||
```
|
||||
|
||||
The same is available from within the REPL via `.update` and `.update v0.4.0`.
|
||||
|
||||
If Coyote was installed with a package manager, prefer that package manager so its
|
||||
records stay in sync with the binary on disk; i.e. `brew upgrade coyote` for Homebrew,
|
||||
or `cargo install --locked coyote-ai` for Cargo.
|
||||
If Loki was installed with a package manager, prefer that package manager so its
|
||||
records stay in sync with the binary on disk; i.e. `brew upgrade loki` for Homebrew,
|
||||
or `cargo install --locked loki-ai` for Cargo.
|
||||
|
||||
When Coyote detects a package-manager install it prints a warning and asks for
|
||||
When Loki detects a package-manager install it prints a warning and asks for
|
||||
confirmation. In a non-interactive shell (no TTY), pass `--force` to update
|
||||
anyway:
|
||||
|
||||
```shell
|
||||
coyote --update --force
|
||||
loki --update --force
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
After installation, you can generate the configuration files and directories by simply running:
|
||||
|
||||
```sh
|
||||
coyote --info
|
||||
loki --info
|
||||
```
|
||||
|
||||
Then, you need to set up the Coyote vault by creating a vault password file. Coyote will do this for you automatically and
|
||||
Then, you need to set up the Loki vault by creating a vault password file. Loki will do this for you automatically and
|
||||
guide you through the process when you first attempt to access the vault. So, to get started, you can run:
|
||||
|
||||
```sh
|
||||
coyote --list-secrets
|
||||
loki --list-secrets
|
||||
```
|
||||
|
||||
### Authentication
|
||||
Each client in your configuration needs authentication (with a few exceptions; e.g. ollama). Most clients use an API key
|
||||
(set via `api_key` in the config or through the [vault](https://github.com/Dark-Alex-17/coyote/wiki/Vault)). For providers that support OAuth (e.g. Claude Pro/Max
|
||||
(set via `api_key` in the config or through the [vault](https://github.com/Dark-Alex-17/loki/wiki/Vault)). For providers that support OAuth (e.g. Claude Pro/Max
|
||||
subscribers, Google Gemini), you can authenticate with your existing subscription instead:
|
||||
|
||||
```yaml
|
||||
# In your config.yaml
|
||||
clients:
|
||||
- type: claude
|
||||
name: my-claude-oauth
|
||||
auth: oauth # Indicate you want to authenticate with OAuth instead of an API key
|
||||
```
|
||||
|
||||
```sh
|
||||
coyote --authenticate my-claude-oauth
|
||||
loki --authenticate claude
|
||||
# Or via the REPL: .authenticate
|
||||
```
|
||||
|
||||
For full details, see the [authentication documentation](https://github.com/Dark-Alex-17/coyote/wiki/Clients#authentication).
|
||||
For full details, see the [authentication documentation](https://github.com/Dark-Alex-17/loki/wiki/Clients#authentication).
|
||||
|
||||
### Tab-Completions
|
||||
You can also enable tab completions to make using Coyote easier. To do so, add the following to your shell profile:
|
||||
You can also enable tab completions to make using Loki easier. To do so, add the following to your shell profile:
|
||||
```shell
|
||||
# Bash
|
||||
# (add to: `~/.bashrc`)
|
||||
source <(COMPLETE=bash coyote)
|
||||
source <(COMPLETE=bash loki)
|
||||
|
||||
# Zsh
|
||||
# (add to: `~/.zshrc`)
|
||||
source <(COMPLETE=zsh coyote)
|
||||
source <(COMPLETE=zsh loki)
|
||||
|
||||
# Fish
|
||||
# (add to: `~/.config/fish/config.fish`)
|
||||
source <(COMPLETE=fish coyote | psub)
|
||||
source <(COMPLETE=fish loki | psub)
|
||||
|
||||
# Elvish
|
||||
# (add to: `~/.elvish/rc.elv`)
|
||||
eval (E:COMPLETE=elvish coyote | slurp)
|
||||
eval (E:COMPLETE=elvish loki | slurp)
|
||||
|
||||
# PowerShell
|
||||
# (add to: `$PROFILE`)
|
||||
$env:COMPLETE = "powershell"
|
||||
coyote | Out-String | Invoke-Expression
|
||||
loki | Out-String | Invoke-Expression
|
||||
```
|
||||
|
||||
### Shell Integration
|
||||
You can integrate Coyote's Shell Assistant into your shell for enhanced command-line assistance. Add the code in the
|
||||
corresponding [shell integration script](./scripts/shell-integration) to your shell. Then, you can invoke Coyote to convert natural language to
|
||||
You can integrate Loki's Shell Assistant into your shell for enhanced command-line assistance. Add the code in the
|
||||
corresponding [shell integration script](./scripts/shell-integration) to your shell. Then, you can invoke Loki to convert natural language to
|
||||
shell commands by pressing `Alt-e`. For example:
|
||||
|
||||
```shell
|
||||
@@ -224,18 +223,18 @@ find . -name "*.md"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
The location of the global Coyote configuration varies between systems, so you can use the following command to find your
|
||||
The location of the global Loki configuration varies between systems, so you can use the following command to find your
|
||||
`config.yaml` file:
|
||||
|
||||
```shell
|
||||
coyote --info | grep 'config_file' | awk '{print $2}'
|
||||
loki --info | grep 'config_file' | awk '{print $2}'
|
||||
```
|
||||
|
||||
The configuration file consists of a number of settings. To see a full example configuration file with every setting
|
||||
defined, refer to the [example configuration file](./config.example.yaml).
|
||||
|
||||
### Default LLM
|
||||
The following settings are available to configure the default LLM that is used when you start Coyote, and its
|
||||
The following settings are available to configure the default LLM that is used when you start Loki, and its
|
||||
hyperparameters:
|
||||
|
||||
| Setting | Description |
|
||||
@@ -245,34 +244,34 @@ hyperparameters:
|
||||
| `top_p` | The default `top_p` hyperparameter value to use for all models, with a range of (0,1) (or (0,2) for some models); <br>Used unless explicitly overridden |
|
||||
|
||||
### CLI Behavior
|
||||
You can use the following settings to modify the behavior of Coyote:
|
||||
You can use the following settings to modify the behavior of Loki:
|
||||
|
||||
| Setting | Default Value | Description |
|
||||
|---------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `stream` | `true` | Controls whether to use stream-style APIs when querying for completions from LLM providers |
|
||||
| `save` | `true` | Controls whether to save each query/response to every model to `messages.md` for posterity; Useful for debugging |
|
||||
| `keybindings` | `emacs` | Specifies which keybinding schema to use; can either be `emacs` or `vi` |
|
||||
| `editor` | `null` | What text editor Coyote should use to edit the input buffer or session (e.g. `vim`, `emacs`, `nano`, `hx`); <br>Defaults to `$EDITOR` |
|
||||
| `editor` | `null` | What text editor Loki should use to edit the input buffer or session (e.g. `vim`, `emacs`, `nano`, `hx`); <br>Defaults to `$EDITOR` |
|
||||
| `wrap` | `no` | Controls whether text is wrapped (can be `no`, `auto`, or some `<max_width>` |
|
||||
| `wrap_code` | `false` | Enables or disables the wrapping of code blocks |
|
||||
|
||||
### Preludes
|
||||
Preludes let you define the default behavior for the different operating modes of Coyote. The available settings are
|
||||
Preludes let you define the default behavior for the different operating modes of Loki. The available settings are
|
||||
shown below:
|
||||
|
||||
| Setting | Description |
|
||||
|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `repl_prelude` | This setting lets you specify a default `session` or `role` to use when starting Coyote in [REPL](https://github.com/Dark-Alex-17/coyote/wiki/REPL) mode. <br>Values can be <ul><li>`role:<name>` to define a role</li><li>`session:<name>` to define a session</li><li>`<session>:<role>` to define both a session and a role to use</li></ul> |
|
||||
| `cmd_prelude` | This setting lets you specify a default `session` or `role` to use when running one-off queries in Coyote via the CLI. <br>Values can be <ul><li>`role:<name>` to define a role</li><li>`session:<name>` to define a session</li><li>`<session>:<role>` to define both a session and a role to use</li></ul> |
|
||||
| `repl_prelude` | This setting lets you specify a default `session` or `role` to use when starting Loki in [REPL](https://github.com/Dark-Alex-17/loki/wiki/REPL) mode. <br>Values can be <ul><li>`role:<name>` to define a role</li><li>`session:<name>` to define a session</li><li>`<session>:<role>` to define both a session and a role to use</li></ul> |
|
||||
| `cmd_prelude` | This setting lets you specify a default `session` or `role` to use when running one-off queries in Loki via the CLI. <br>Values can be <ul><li>`role:<name>` to define a role</li><li>`session:<name>` to define a session</li><li>`<session>:<role>` to define both a session and a role to use</li></ul> |
|
||||
| `agent_session` | This setting is used to specify a default session that all agents should start into, unless otherwise specified in the agent configuration. (e.g. `temp`, `default`) |
|
||||
|
||||
### Appearance
|
||||
The appearance of Coyote can be modified using the following settings:
|
||||
The appearance of Loki can be modified using the following settings:
|
||||
|
||||
| Setting | Default Value | Description |
|
||||
|---------------|---------------|------------------------------------------------------|
|
||||
| `highlight` | `true` | This setting enables or disables syntax highlighting |
|
||||
| `light_theme` | `false` | This setting toggles light mode in Coyote |
|
||||
| `light_theme` | `false` | This setting toggles light mode in Loki |
|
||||
|
||||
### Miscellaneous Settings
|
||||
| Setting | Default Value | Description |
|
||||
@@ -284,7 +283,7 @@ The appearance of Coyote can be modified using the following settings:
|
||||
|
||||
## History
|
||||
|
||||
Coyote began as a fork of [AIChat CLI](https://github.com/sigoden/aichat) and has since evolved into an independent project.
|
||||
Loki began as a fork of [AIChat CLI](https://github.com/sigoden/aichat) and has since evolved into an independent project.
|
||||
|
||||
See [CREDITS.md](./CREDITS.md) for full attribution and background.
|
||||
|
||||
|
||||
@@ -7,14 +7,14 @@ set -euo pipefail
|
||||
#######################
|
||||
|
||||
# Cache file name for detected project info
|
||||
_COYOTE_PROJECT_CACHE=".coyote-project.json"
|
||||
_LOKI_PROJECT_CACHE=".loki-project.json"
|
||||
|
||||
# Read cached project detection if valid
|
||||
# Usage: _read_project_cache "/path/to/project"
|
||||
# Returns: cached JSON on stdout (exit 0) or nothing (exit 1)
|
||||
_read_project_cache() {
|
||||
local dir="$1"
|
||||
local cache_file="${dir}/${_COYOTE_PROJECT_CACHE}"
|
||||
local cache_file="${dir}/${_LOKI_PROJECT_CACHE}"
|
||||
|
||||
if [[ -f "${cache_file}" ]]; then
|
||||
local cached
|
||||
@@ -32,7 +32,7 @@ _read_project_cache() {
|
||||
_write_project_cache() {
|
||||
local dir="$1"
|
||||
local json="$2"
|
||||
local cache_file="${dir}/${_COYOTE_PROJECT_CACHE}"
|
||||
local cache_file="${dir}/${_LOKI_PROJECT_CACHE}"
|
||||
|
||||
echo "${json}" > "${cache_file}" 2>/dev/null || true
|
||||
}
|
||||
@@ -238,7 +238,7 @@ _detect_with_llm() {
|
||||
)
|
||||
|
||||
local llm_response
|
||||
llm_response=$(coyote --no-stream "${prompt}" 2>/dev/null) || return 1
|
||||
llm_response=$(loki --no-stream "${prompt}" 2>/dev/null) || return 1
|
||||
|
||||
llm_response=$(echo "${llm_response}" | sed 's/^```json//;s/^```//;s/```$//' | tr -d '\n' | sed 's/^[[:space:]]*//')
|
||||
llm_response=$(echo "${llm_response}" | grep -o '{[^}]*}' | head -1)
|
||||
|
||||
@@ -4,7 +4,7 @@ A graph-based implementation agent. Plans, implements, and runs build +
|
||||
tests in a bounded fix-loop until verified. Designed to be delegated to by
|
||||
the **[Sisyphus](../sisyphus/README.md)** agent.
|
||||
|
||||
Coder is a [graph agent](https://github.com/Dark-Alex-17/coyote/wiki/Graph-Agents): its workflow is
|
||||
Coder is a [graph agent](https://github.com/Dark-Alex-17/loki/wiki/Graph-Agents): its workflow is
|
||||
defined declaratively in `graph.yaml`, with verification and the
|
||||
implement-fix loop enforced as graph edges rather than prose.
|
||||
|
||||
@@ -42,10 +42,10 @@ so it accepts the runtime override flag:
|
||||
```sh
|
||||
# Invoke from inside the project (project_dir defaults to ".")
|
||||
cd /path/to/your/project
|
||||
coyote -a coder "Add a foo() function..."
|
||||
loki -a coder "Add a foo() function..."
|
||||
|
||||
# Or invoke from anywhere with an explicit override
|
||||
coyote -a coder --agent-variable project_dir /path/to/your/project "Add..."
|
||||
loki -a coder --agent-variable project_dir /path/to/your/project "Add..."
|
||||
```
|
||||
|
||||
`graph.yaml` `initial_state` exposes:
|
||||
|
||||
@@ -17,8 +17,8 @@ variables:
|
||||
- name: project_dir
|
||||
description: |
|
||||
Absolute path to the project directory. Defaults to "." which is the
|
||||
directory you invoked `coyote` from. Override at runtime with
|
||||
`coyote -a coder --agent-variable project_dir /abs/path "..."`.
|
||||
directory you invoked `loki` from. Override at runtime with
|
||||
`loki -a coder --agent-variable project_dir /abs/path "..."`.
|
||||
default: "."
|
||||
|
||||
settings:
|
||||
@@ -70,7 +70,7 @@ nodes:
|
||||
MUST be absolute. The project root is {{project_dir}}. Prefer paths
|
||||
like "{{project_dir}}/src/foo.rs" over "src/foo.rs". The implementer
|
||||
uses these paths directly with fs_write and fs_patch tools, which
|
||||
resolve relative paths against the coyote invocation directory (NOT
|
||||
resolve relative paths against the loki invocation directory (NOT
|
||||
the project dir). Empty arrays are fine if no files in that category.
|
||||
|
||||
`risks` is a list of short strings. Anything that could derail the
|
||||
@@ -155,7 +155,7 @@ nodes:
|
||||
2. Use `fs_write` for new files or full rewrites.
|
||||
3. NEVER output code to chat. Always use tools.
|
||||
4. ALWAYS pass ABSOLUTE paths to fs_write and fs_patch. Relative
|
||||
paths resolve against the coyote invocation directory (not the
|
||||
paths resolve against the loki invocation directory (not the
|
||||
project dir), which is rarely what you want. The project root
|
||||
is {{project_dir}}.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# deep-research
|
||||
|
||||
A deep web research agent, built as a Coyote graph agent. It plans an
|
||||
A deep web research agent, built as a Loki graph agent. It plans an
|
||||
investigation, decomposes it into sub-questions researched in
|
||||
parallel, grounds the work in a local knowledge corpus, vets the
|
||||
credibility of cited sources, runs a reflexion self-critique loop to
|
||||
@@ -13,12 +13,12 @@ this agent runs a fixed graph: every request goes through the same
|
||||
`plan -> parallel research -> vet -> critique -> synthesize -> verify -> approve`
|
||||
pipeline.
|
||||
|
||||
This agent is also the **canonical reference for the Coyote graph
|
||||
This agent is also the **canonical reference for the Loki graph
|
||||
system**: it exercises every node type (`script`, `llm`, `rag`, `map`,
|
||||
`agent`, `input`, `approval`, `end`) and both static fan-out and
|
||||
dynamic `map` fan-out. If you are learning how to build a graph
|
||||
agent, this is the file to read alongside the
|
||||
[Graph-Agents wiki](https://github.com/Dark-Alex-17/coyote/wiki/Graph-Agents).
|
||||
[Graph-Agents wiki](https://github.com/Dark-Alex-17/loki/wiki/Graph-Agents).
|
||||
|
||||
## Workflow
|
||||
|
||||
@@ -48,21 +48,21 @@ incorporate_feedback (script) -> research_each_question (the human-feedbac
|
||||
|
||||
### Node-type breakdown
|
||||
|
||||
| Type | Nodes |
|
||||
|-----------------------------|-----------------------------------------------------------------------------------------------------------------------|
|
||||
| `script` (Python) | `parse_request`, `bootstrap_research`, `combine_findings`, `reflexion_gate`, `verify_sources`, `incorporate_feedback` |
|
||||
| `llm` (tools: `[]`) | `plan`, `critique` |
|
||||
| `llm` (with tool whitelist) | `research_one_question`, `vet_sources` |
|
||||
| `rag` | `knowledge_lookup` — local corpus retrieval |
|
||||
| `map` | `research_each_question` — dynamic fan-out per sub-question |
|
||||
| `agent` | `synthesize` — spawns the `report-writer` sub-agent |
|
||||
| `input` | `ask_topic` |
|
||||
| `approval` | `approve` |
|
||||
| `end` | `end_accepted`, `end_rejected` |
|
||||
| Type | Nodes |
|
||||
|---|---|
|
||||
| `script` (Python) | `parse_request`, `bootstrap_research`, `combine_findings`, `reflexion_gate`, `verify_sources`, `incorporate_feedback` |
|
||||
| `llm` (tools: `[]`) | `plan`, `critique` |
|
||||
| `llm` (with tool whitelist) | `research_one_question`, `vet_sources` |
|
||||
| `rag` | `knowledge_lookup` — local corpus retrieval |
|
||||
| `map` | `research_each_question` — dynamic fan-out per sub-question |
|
||||
| `agent` | `synthesize` — spawns the `report-writer` sub-agent |
|
||||
| `input` | `ask_topic` |
|
||||
| `approval` | `approve` |
|
||||
| `end` | `end_accepted`, `end_rejected` |
|
||||
|
||||
## Parallel execution
|
||||
|
||||
The graph has two parallel super-steps where Coyote's BSP scheduler runs
|
||||
The graph has two parallel super-steps where Loki's BSP scheduler runs
|
||||
branches concurrently.
|
||||
|
||||
**1. Context loading (`plan` ‖ `knowledge_lookup`)** — after
|
||||
@@ -96,7 +96,7 @@ PDFs, or text files into `knowledge/` to bias the research toward
|
||||
your local context.
|
||||
|
||||
The knowledge base is built once, at agent-load time, into
|
||||
`~/.config/coyote/agents/deep-research/knowledge_lookup.yaml`. Because
|
||||
`~/.config/loki/agents/deep-research/knowledge_lookup.yaml`. Because
|
||||
the node fully specifies its build config (`embedding_model`,
|
||||
`chunk_size`, `chunk_overlap`), the build is non-interactive. Delete
|
||||
that cached file after adding or changing knowledge to force a
|
||||
@@ -119,13 +119,13 @@ for details.
|
||||
|
||||
## Tools and tool scoping
|
||||
|
||||
This agent demonstrates Coyote's three tool sources and how an `llm`
|
||||
This agent demonstrates Loki's three tool sources and how an `llm`
|
||||
node's `tools:` whitelist scopes them per node.
|
||||
|
||||
The agent's full tool universe, declared in `graph.yaml`:
|
||||
|
||||
- **Global tools** (`global_tools`): `web_search_coyote`,
|
||||
`fetch_url_via_curl`, `search_arxiv` - Coyote's built-in tool scripts.
|
||||
- **Global tools** (`global_tools`): `web_search_loki`,
|
||||
`fetch_url_via_curl`, `search_arxiv` - Loki's built-in tool scripts.
|
||||
- **MCP server** (`mcp_servers`): `ddg-search` - a DuckDuckGo web
|
||||
search MCP server. Referenced in a whitelist as `mcp:ddg-search`.
|
||||
- **Custom agent tool** (`tools.sh`): `classify_source` - a
|
||||
@@ -134,11 +134,11 @@ The agent's full tool universe, declared in `graph.yaml`:
|
||||
No node receives all of these. Each `llm` node's `tools:` whitelist
|
||||
narrows the universe to exactly what that step needs:
|
||||
|
||||
| Node | `tools:` whitelist | Draws from |
|
||||
|-------------------------|-----------------------------------------------------------------------------|--------------------------|
|
||||
| `plan`, `critique` | `[]` | nothing - pure reasoning |
|
||||
| `research_one_question` | `web_search_coyote`, `fetch_url_via_curl`, `search_arxiv`, `mcp:ddg-search` | global tools + MCP |
|
||||
| `vet_sources` | `classify_source` | the custom tool only |
|
||||
| Node | `tools:` whitelist | Draws from |
|
||||
|---|---|---|
|
||||
| `plan`, `critique` | `[]` | nothing - pure reasoning |
|
||||
| `research_one_question` | `web_search_loki`, `fetch_url_via_curl`, `search_arxiv`, `mcp:ddg-search` | global tools + MCP |
|
||||
| `vet_sources` | `classify_source` | the custom tool only |
|
||||
|
||||
`research_one_question` (each parallel branch of the map) can search
|
||||
and fetch but cannot classify sources; `vet_sources` can classify
|
||||
@@ -153,21 +153,21 @@ deterministic - exactly the kind of logic a tool should own rather than
|
||||
the LLM guessing.
|
||||
|
||||
Web search may require API-key configuration; see the
|
||||
[Tools](https://github.com/Dark-Alex-17/coyote/wiki/Tools) docs.
|
||||
[Tools](https://github.com/Dark-Alex-17/loki/wiki/Tools) docs.
|
||||
`fetch_url_via_curl`, `search_arxiv`, and `classify_source` work
|
||||
without a key.
|
||||
|
||||
## Setup
|
||||
|
||||
`research_one_question` (each parallel branch of the `map`) uses the
|
||||
`ddg-search` MCP server via `mcp:ddg-search`. It is one of Coyote's
|
||||
`ddg-search` MCP server via `mcp:ddg-search`. It is one of Loki's
|
||||
default MCP servers; make sure it is registered in
|
||||
`~/.config/coyote/mcp.json` (run `coyote --install mcp_config` to restore
|
||||
`~/.config/loki/mcp.json` (run `loki --install mcp_config` to restore
|
||||
the default template if it is missing). If `ddg-search` is unavailable,
|
||||
the branches still have their global web-search tools to fall back on.
|
||||
|
||||
The `synthesize` node spawns the `report-writer` sub-agent. Both
|
||||
agents ship with `coyote agents install`; if you install one manually,
|
||||
agents ship with `loki agents install`; if you install one manually,
|
||||
install both so the agent reference resolves.
|
||||
|
||||
## Reflexion
|
||||
@@ -205,10 +205,10 @@ backstop: it caps the total visits to any single node.
|
||||
## Running
|
||||
|
||||
```sh
|
||||
coyote agents install # ships deep-research
|
||||
coyote -a deep-research "How does HTTP/3 differ from HTTP/2?"
|
||||
coyote -a deep-research "Recent advances in solid-state batteries"
|
||||
coyote -a deep-research # no prompt -> triggers ask_topic
|
||||
loki agents install # ships deep-research
|
||||
loki -a deep-research "How does HTTP/3 differ from HTTP/2?"
|
||||
loki -a deep-research "Recent advances in solid-state batteries"
|
||||
loki -a deep-research # no prompt -> triggers ask_topic
|
||||
```
|
||||
|
||||
## Anti-hallucination
|
||||
@@ -240,7 +240,7 @@ coyote -a deep-research # no prompt -> triggers ask_topic
|
||||
`report-writer` sub-agent.
|
||||
- **Tool scope.** Narrow the `research_one_question` node's `tools:`
|
||||
list to constrain where each branch looks (for example, drop
|
||||
`web_search_coyote` and `mcp:ddg-search` to force arXiv-only
|
||||
`web_search_loki` and `mcp:ddg-search` to force arXiv-only
|
||||
research).
|
||||
- **Local knowledge.** Drop files into `knowledge/` to bias every
|
||||
research branch toward your local context (see the *Local
|
||||
|
||||
@@ -9,7 +9,7 @@ description: |
|
||||
approval. A reviewer's free-form feedback at the approval step feeds
|
||||
back into another research pass.
|
||||
|
||||
This is the canonical Coyote graph-agent reference: it exercises every
|
||||
This is the canonical Loki graph-agent reference: it exercises every
|
||||
node type (script, llm, rag, map, agent, input, approval, end) and
|
||||
both static fan-out and dynamic map fan-out.
|
||||
|
||||
@@ -18,7 +18,7 @@ version: "1.0"
|
||||
temperature: 0.0
|
||||
|
||||
global_tools:
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
- fetch_url_via_curl.sh
|
||||
- search_arxiv.sh
|
||||
|
||||
@@ -147,7 +147,7 @@ nodes:
|
||||
|
||||
{{research_feedback}}
|
||||
tools:
|
||||
- web_search_coyote
|
||||
- web_search_loki
|
||||
- fetch_url_via_curl
|
||||
- search_arxiv
|
||||
- mcp:ddg-search
|
||||
|
||||
@@ -5,7 +5,7 @@ hybrid (vector + keyword) retrieval over every file in this directory.
|
||||
Drop your own notes, papers (PDFs), Markdown docs, or text files here
|
||||
and they will be indexed into a per-agent knowledge base on first run.
|
||||
|
||||
Coyote supports common file types out of the box: `.md`, `.txt`, `.pdf`,
|
||||
Loki supports common file types out of the box: `.md`, `.txt`, `.pdf`,
|
||||
`.html`, and others. Subdirectories are walked recursively.
|
||||
|
||||
A small starter file (`research-style-notes.md`) ships so the RAG
|
||||
@@ -17,7 +17,7 @@ To force the knowledge base to rebuild after you add or change files,
|
||||
delete the cached index:
|
||||
|
||||
```sh
|
||||
rm ~/.config/coyote/agents/deep-research/knowledge_lookup.yaml
|
||||
rm ~/.config/loki/agents/deep-research/knowledge_lookup.yaml
|
||||
```
|
||||
|
||||
The next run will rebuild from the current contents of this directory.
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
This agent serves as a demo to guide agent development and showcase various agent capabilities.
|
||||
|
||||
To enable tools, Coyote will look for the first `tools.py` or `tools.sh` file it finds in this directory.
|
||||
To enable tools, Loki will look for the first `tools.py` or `tools.sh` file it finds in this directory.
|
||||
|
||||
The base configuration using `tools.py`. To switch to using `tools.sh`, rename or remove `tools.py`.
|
||||
|
||||
@@ -17,7 +17,7 @@ It can also be used as a standalone tool for understanding codebases and finding
|
||||
## Pro-Tip: Use an IDE MCP Server for Improved Performance
|
||||
Many modern IDEs now include MCP servers that let LLMs perform operations within the IDE itself and use IDE tools. Using
|
||||
an IDE's MCP server dramatically improves the performance of coding agents. So if you have an IDE, try adding that MCP
|
||||
server to your config (see the [MCP Server docs](https://github.com/Dark-Alex-17/loki/wiki/MCP-Servers) to see how to configure
|
||||
server to your config (see the [MCP Server docs](../../../docs/function-calling/MCP-SERVERS.md) to see how to configure
|
||||
them), and modify the agent definition to look like this:
|
||||
|
||||
```yaml
|
||||
@@ -31,7 +31,7 @@ global_tools:
|
||||
- fs_grep.sh
|
||||
- fs_glob.sh
|
||||
- fs_ls.sh
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ It can also be used as a standalone tool for design reviews and solving difficul
|
||||
## Pro-Tip: Use an IDE MCP Server for Improved Performance
|
||||
Many modern IDEs now include MCP servers that let LLMs perform operations within the IDE itself and use IDE tools. Using
|
||||
an IDE's MCP server dramatically improves the performance of coding agents. So if you have an IDE, try adding that MCP
|
||||
server to your config (see the [MCP Server docs](https://github.com/Dark-Alex-17/loki/wiki/MCP-Servers) to see how to configure
|
||||
server to your config (see the [MCP Server docs](../../../docs/function-calling/MCP-SERVERS.md) to see how to configure
|
||||
them), and modify the agent definition to look like this:
|
||||
|
||||
```yaml
|
||||
@@ -33,7 +33,7 @@ global_tools:
|
||||
- fs_grep.sh
|
||||
- fs_glob.sh
|
||||
- fs_ls.sh
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ You can also use this agent directly if you have a set of findings you
|
||||
want polished:
|
||||
|
||||
```sh
|
||||
coyote -a report-writer "Topic: X. Findings: <paste findings here>"
|
||||
loki -a report-writer "Topic: X. Findings: <paste findings here>"
|
||||
```
|
||||
|
||||
It will produce a single Markdown report following the rules in its
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Sisyphus
|
||||
|
||||
The main coordinator agent for the Coyote coding ecosystem, providing a powerful CLI interface for code generation and
|
||||
The main coordinator agent for the Loki coding ecosystem, providing a powerful CLI interface for code generation and
|
||||
project management similar to OpenCode, ClaudeCode, Codex, or Gemini CLI.
|
||||
|
||||
_Inspired by the Sisyphus and Oracle agents of OpenCode._
|
||||
@@ -19,8 +19,8 @@ Sisyphus acts as the primary entry point, capable of handling complex tasks by c
|
||||
|
||||
## Pro-Tip: Use an IDE MCP Server for Improved Performance
|
||||
Many modern IDEs (JetBrains, VS Code, Cursor, Zed, etc.) expose MCP servers that let LLMs use IDE tools directly. Using
|
||||
one dramatically improves the performance of coding agents. If you have one, add it to your coyote config (see the
|
||||
[MCP Server docs](https://github.com/Dark-Alex-17/loki/wiki/MCP-Servers)) and reference it in this agent's `mcp_servers:` list:
|
||||
one dramatically improves the performance of coding agents. If you have one, add it to your loki config (see the
|
||||
[MCP Server docs](../../../docs/function-calling/MCP-SERVERS.md)) and reference it in this agent's `mcp_servers:` list:
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
@@ -33,7 +33,7 @@ global_tools:
|
||||
- fs_grep.sh
|
||||
- fs_glob.sh
|
||||
- fs_ls.sh
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
- execute_command.sh
|
||||
|
||||
# ...
|
||||
|
||||
+1106
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -6,11 +6,11 @@ set -e
|
||||
|
||||
# @option --query! The search query.
|
||||
|
||||
# @meta require-tools coyote
|
||||
# @meta require-tools loki
|
||||
|
||||
# @env WEB_SEARCH_MODEL=gemini:gemini-2.5-flash The model for web-searching.
|
||||
#
|
||||
# supported coyote models:
|
||||
# supported loki models:
|
||||
# - gemini:gemini-2.0-*
|
||||
# - vertexai:gemini-*
|
||||
# - perplexity:*
|
||||
@@ -22,15 +22,15 @@ main() {
|
||||
client="${WEB_SEARCH_MODEL%%:*}"
|
||||
|
||||
if [[ "$client" == "gemini" ]]; then
|
||||
export COYOTE_PATCH_GEMINI_CHAT_COMPLETIONS='{".*":{"body":{"tools":[{"google_search":{}}]}}}'
|
||||
export LOKI_PATCH_GEMINI_CHAT_COMPLETIONS='{".*":{"body":{"tools":[{"google_search":{}}]}}}'
|
||||
elif [[ "$client" == "vertexai" ]]; then
|
||||
export COYOTE_PATCH_VERTEXAI_CHAT_COMPLETIONS='{
|
||||
export LOKI_PATCH_VERTEXAI_CHAT_COMPLETIONS='{
|
||||
"gemini-1.5-.*":{"body":{"tools":[{"googleSearchRetrieval":{}}]}},
|
||||
"gemini-2.0-.*":{"body":{"tools":[{"google_search":{}}]}}
|
||||
}'
|
||||
elif [[ "$client" == "ernie" ]]; then
|
||||
export COYOTE_PATCH_ERNIE_CHAT_COMPLETIONS='{".*":{"body":{"web_search":{"enable":true}}}}'
|
||||
export LOKI_PATCH_ERNIE_CHAT_COMPLETIONS='{".*":{"body":{"web_search":{"enable":true}}}}'
|
||||
fi
|
||||
|
||||
coyote -m "$WEB_SEARCH_MODEL" "$argc_query" >> "$LLM_OUTPUT"
|
||||
loki -m "$WEB_SEARCH_MODEL" "$argc_query" >> "$LLM_OUTPUT"
|
||||
}
|
||||
@@ -506,14 +506,16 @@ open_link() {
|
||||
}
|
||||
|
||||
guard_operation() {
|
||||
if [[ -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then
|
||||
ans="$(confirm "${1:-Are you sure you want to continue?}")"
|
||||
if [[ -t 1 ]]; then
|
||||
if [[ -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then
|
||||
ans="$(confirm "${1:-Are you sure you want to continue?}")"
|
||||
|
||||
if [[ "$ans" == 0 ]]; then
|
||||
error "Operation aborted!" 2>&1
|
||||
exit 1
|
||||
if [[ "$ans" == 0 ]]; then
|
||||
error "Operation aborted!" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Here is an example of a patch block that can be applied to modify the file to request the user's name:
|
||||
@@ -653,17 +655,19 @@ guard_path() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
path="$(_to_real_path "$1")"
|
||||
confirmation_prompt="$2"
|
||||
if [[ -t 1 ]]; then
|
||||
path="$(_to_real_path "$1")"
|
||||
confirmation_prompt="$2"
|
||||
|
||||
if [[ ! "$path" == "$(pwd)"* && -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then
|
||||
ans="$(confirm "$confirmation_prompt")"
|
||||
if [[ ! "$path" == "$(pwd)"* && -z "$AUTO_CONFIRM" && -z "$LLM_AGENT_VAR_AUTO_CONFIRM" ]]; then
|
||||
ans="$(confirm "$confirmation_prompt")"
|
||||
|
||||
if [[ "$ans" == 0 ]]; then
|
||||
error "Operation aborted!" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ "$ans" == 0 ]]; then
|
||||
error "Operation aborted!" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
_to_real_path() {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ security/configuration settings. The analysis aims to ensure a thorough understa
|
||||
structured and operates, enabling the creation of new files, maintaining consistency with existing practices, and the
|
||||
potential implementation of best practices.
|
||||
|
||||
Should the root directory contain a `COYOTE.md` file, this was generated by Coyote and should be used as a reference
|
||||
Should the root directory contain a `LOKI.md` file, this was generated by Loki and should be used as a reference
|
||||
point for all analysis, style questions, etc.
|
||||
|
||||
**Objective:** Enable the AI to thoroughly analyze a software repository, providing detailed insights and guidelines on
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Agent-specific configuration
|
||||
# Location `<coyote-config-dir>/agents/<agent-name>/config.yaml`
|
||||
# Location `<loki-config-dir>/agents/<agent-name>/config.yaml`
|
||||
#
|
||||
# Available Environment Variables:
|
||||
# - <agent-name>_MODEL
|
||||
@@ -21,14 +21,14 @@ version: 1 # Version of the agent
|
||||
# The auto-continue system provides built-in task tracking for improved reliability.
|
||||
# When enabled, the model can create todo lists and the system will automatically
|
||||
# prompt it to continue when incomplete tasks remain.
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/coyote/wiki/TODO-System) for more information
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/loki/wiki/TODO-System) for more information
|
||||
auto_continue: false # Enable automatic continuation when incomplete todos remain
|
||||
max_auto_continues: 10 # Maximum number of automatic continuations before stopping
|
||||
inject_todo_instructions: true # Inject the default todo tool usage instructions into the agent's system prompt
|
||||
continuation_prompt: null # Custom prompt used when auto-continuing (optional; uses default if null)
|
||||
# Sub-Agent Spawning System
|
||||
# Enable this agent to spawn and manage child agents in parallel.
|
||||
# See https://github.com/Dark-Alex-17/coyote/wiki/Agents for detailed documentation.
|
||||
# See https://github.com/Dark-Alex-17/loki/wiki/Agents for detailed documentation.
|
||||
can_spawn_agents: false # Enable the agent to spawn child agents
|
||||
max_concurrent_agents: 4 # Maximum number of agents that can run simultaneously
|
||||
max_agent_depth: 3 # Maximum nesting depth for sub-agents (prevents runaway spawning)
|
||||
@@ -37,7 +37,7 @@ summarization_model: null # Model to use for summarizing sub-agent output
|
||||
summarization_threshold: 4000 # Character threshold above which sub-agent output is summarized before returning to parent
|
||||
escalation_timeout: 300 # Seconds a sub-agent waits for a user interaction response before timing out (default: 5 minutes)
|
||||
mcp_servers: # Optional list of MCP servers that the agent utilizes
|
||||
- github # Corresponds to the name of an MCP server in the `<coyote-config-dir>/functions/mcp.json` file
|
||||
- github # Corresponds to the name of an MCP server in the `<loki-config-dir>/functions/mcp.json` file
|
||||
global_tools: # Optional list of additional global tools to enable for the agent; i.e. not tools specific to the agent
|
||||
- web_search
|
||||
- fs
|
||||
@@ -80,10 +80,10 @@ conversation_starters: # Optional conversation starters for the agent
|
||||
- What is the best way to exercise?
|
||||
- How do I manage my time effectively?
|
||||
documents: # Optional documents to load for the agent
|
||||
- git:/some/repo # Explicitly tell Coyote to use the 'git' document loader using an absolute path
|
||||
- pdf:some-pdf-file.pdf # Explicitly tell Coyote to use the 'pdf' document loader using a relative path
|
||||
- git:/some/repo # Explicitly tell Loki to use the 'git' document loader using an absolute path
|
||||
- pdf:some-pdf-file.pdf # Explicitly tell Loki to use the 'pdf' document loader using a relative path
|
||||
- https://some-website.com/some-page
|
||||
- some-file.pdf # File with relative path to the <coyote-config-dir>/agents/<agent-name> directory; i.e. file in the same directory as this config file
|
||||
- some-file.pdf # File with relative path to the <loki-config-dir>/agents/<agent-name> directory; i.e. file in the same directory as this config file
|
||||
- ~/some-file.txt # File in the user's home directory
|
||||
- /absolute/path/to/some-file.md # File with absolute path
|
||||
- /absolute/path/**/NAME.txt # Find all NAME.txt files in the specified directory and all its subdirectories
|
||||
|
||||
+46
-46
@@ -18,31 +18,31 @@ agent_session: null # Set a session to use when starting an agent (
|
||||
|
||||
# ---- Appearance ----
|
||||
highlight: true # Controls syntax highlighting
|
||||
light_theme: false # Activates a light color theme when true. env: COYOTE_LIGHT_THEME
|
||||
light_theme: false # Activates a light color theme when true. env: LOKI_LIGHT_THEME
|
||||
|
||||
# ---- Miscellaneous ----
|
||||
user_agent: null # Set User-Agent HTTP header, use `auto` for coyote/<current-version>
|
||||
user_agent: null # Set User-Agent HTTP header, use `auto` for loki/<current-version>
|
||||
save_shell_history: true # Whether to save shell execution command to the history file
|
||||
sync_models_url: > # URL to sync model changes from
|
||||
https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml
|
||||
https://raw.githubusercontent.com/Dark-Alex-17/loki/refs/heads/main/models.yaml
|
||||
|
||||
# ---- REPL Prompt ----
|
||||
# Custom REPL left/right prompts; see the [REPL Prompt Documentation](https://github.com/Dark-Alex-17/coyote/wiki/REPL-Prompt) for more information
|
||||
# Custom REPL left/right prompts; see the [REPL Prompt Documentation](https://github.com/Dark-Alex-17/loki/wiki/REPL-Prompt) for more information
|
||||
left_prompt:
|
||||
'{color.red}{model}){color.green}{?session {?agent {agent}>}{session}{?role /}}{!session {?agent {agent}>}}{role}{?rag @{rag}}{color.cyan}{?session )}{!session >}{color.reset} '
|
||||
right_prompt:
|
||||
'{color.purple}{?session {?consume_tokens {consume_tokens}({consume_percent}%)}{!consume_tokens {consume_tokens}}}{color.reset}'
|
||||
|
||||
# ---- Vault ----
|
||||
# See the [Vault documentation](https://github.com/Dark-Alex-17/coyote/wiki/Vault) for more information on the Coyote vault
|
||||
vault_password_file: null # Path to a file containing the password for the Coyote vault (cannot be a secret template)
|
||||
# See the [Vault documentation](https://github.com/Dark-Alex-17/loki/wiki/Vault) for more information on the Loki vault
|
||||
vault_password_file: null # Path to a file containing the password for the Loki vault (cannot be a secret template)
|
||||
|
||||
# ---- Function Calling ----
|
||||
# See the [Tools documentation](https://github.com/Dark-Alex-17/coyote/wiki/Tools) for more details
|
||||
# See the [Tools documentation](https://github.com/Dark-Alex-17/loki/wiki/Tools) for more details
|
||||
function_calling: true # Enables or disables function calling (Globally).
|
||||
mapping_tools: # Alias for a tool or toolset
|
||||
fs: 'fs_cat,fs_ls,fs_mkdir,fs_rm,fs_write,fs_read,fs_glob,fs_grep'
|
||||
enabled_tools: null # Which tools to enable by default. (e.g. 'fs,web_search_coyote')
|
||||
enabled_tools: null # Which tools to enable by default. (e.g. 'fs,web_search_loki')
|
||||
visible_tools: # Which tools are visible to be compiled (and are thus able to be defined in 'enabled_tools')
|
||||
# - demo_py.py
|
||||
# - demo_sh.sh
|
||||
@@ -69,12 +69,12 @@ visible_tools: # Which tools are visible to be compiled (and a
|
||||
# - search_wolframalpha.sh
|
||||
# - send_mail.sh
|
||||
# - send_twilio.sh
|
||||
# - web_search_coyote.sh
|
||||
# - web_search_loki.sh
|
||||
# - web_search_perplexity.sh
|
||||
# - web_search_tavily.sh
|
||||
|
||||
# ---- MCP Servers ----
|
||||
# See the [MCP Servers documentation](https://github.com/Dark-Alex-17/coyote/wiki/MCP-Servers) for more details
|
||||
# See the [MCP Servers documentation](https://github.com/Dark-Alex-17/loki/wiki/MCP-Servers) for more details
|
||||
mcp_server_support: true # Enables or disables MCP servers (globally).
|
||||
mapping_mcp_servers: # Alias for an MCP server or set of servers
|
||||
git: github,gitmcp
|
||||
@@ -84,14 +84,14 @@ enabled_mcp_servers: null # Which MCP servers to enable by default (e.g.
|
||||
# The auto-continue system provides built-in task tracking for improved reliability.
|
||||
# When enabled, the model can create todo lists and the system will automatically
|
||||
# prompt it to continue when incomplete tasks remain.
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/coyote/wiki/TODO-System) for more information
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/loki/wiki/TODO-System) for more information
|
||||
auto_continue: false # Enable automatic continuation when incomplete todos remain (default: false)
|
||||
max_auto_continues: 10 # Maximum number of automatic continuations before stopping (default: 10)
|
||||
inject_todo_instructions: true # Inject default todo usage instructions into the system prompt (default: true)
|
||||
continuation_prompt: null # Custom prompt used when auto-continuing. If null, uses built-in default
|
||||
|
||||
# ---- Session ----
|
||||
# See the [Session documentation](https://github.com/Dark-Alex-17/coyote/wiki/Sessions) for more information
|
||||
# See the [Session documentation](https://github.com/Dark-Alex-17/loki/wiki/Sessions) for more information
|
||||
save_session: null # Controls the persistence of the session. If true, auto save; if false, don't auto-save save; if null, ask the user what to do
|
||||
compression_threshold: 4000 # Compress the session when the token count reaches or exceeds this threshold
|
||||
summarization_prompt: > # The text prompt used for creating a concise summary of session message
|
||||
@@ -100,9 +100,9 @@ summary_context_prompt: > # The text prompt used for including the summar
|
||||
'This is a summary of the chat history as a recap: '
|
||||
|
||||
# ---- RAG ----
|
||||
# See the [RAG Docs](https://github.com/Dark-Alex-17/coyote/wiki/RAG) for more details.
|
||||
# See the [RAG Docs](https://github.com/Dark-Alex-17/loki/wiki/RAG) for more details.
|
||||
rag_embedding_model: null # Specifies the embedding model used for context retrieval
|
||||
rag_reranker_model: null # Specifies the reranker model used for sorting retrieved documents; Coyote uses Reciprocal Rank Fusion by default
|
||||
rag_reranker_model: null # Specifies the reranker model used for sorting retrieved documents; Loki uses Reciprocal Rank Fusion by default
|
||||
rag_top_k: 5 # Specifies the number of documents to retrieve for answering queries
|
||||
rag_chunk_size: null # Defines the size of chunks for document processing in characters
|
||||
rag_chunk_overlap: null # Defines the overlap between chunks
|
||||
@@ -141,12 +141,12 @@ document_loaders:
|
||||
docx: 'pandoc --to plain $1' # Use pandoc to convert a .docx file to text
|
||||
# (see https://pandoc.org for details on how to install pandoc)
|
||||
jina: 'curl -fsSL https://r.jina.ai/$1 -H "Authorization: Bearer {{JINA_API_KEY}}' # Use Jina to translate a website into text;
|
||||
# Requires a Jina API key to be added to the Coyote vault
|
||||
# Requires a Jina API key to be added to the Loki vault
|
||||
git: > # Use yek to load a git repository into the knowledgebase (https://github.com/bodo-run/yek)
|
||||
sh -c "yek $1 --json | jq 'map({ path: .filename, contents: .content })'"
|
||||
|
||||
# ---- Clients ----
|
||||
# See the [Clients documentation](https://github.com/Dark-Alex-17/coyote/wiki/Clients) for more details
|
||||
# See the [Clients documentation](https://github.com/Dark-Alex-17/loki/wiki/Clients) for more details
|
||||
clients:
|
||||
# All clients have the following configuration:
|
||||
# - type: xxxx
|
||||
@@ -177,14 +177,14 @@ clients:
|
||||
# See https://platform.openai.com/docs/quickstart
|
||||
- type: openai
|
||||
api_base: https://api.openai.com/v1 # Optional
|
||||
api_key: '{{OPENAI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{OPENAI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
organization_id: org-xxx # Optional
|
||||
|
||||
# For any platform compatible with OpenAI's API
|
||||
- type: openai-compatible
|
||||
name: ollama
|
||||
api_base: http://localhost:11434/v1
|
||||
api_key: '{{OLLAMA_API_KEY}}' # Optional; You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{OLLAMA_API_KEY}}' # Optional; You can either hard-code or inject secrets from the Loki vault
|
||||
models:
|
||||
- name: deepseek-r1
|
||||
max_input_tokens: 131072
|
||||
@@ -202,9 +202,9 @@ clients:
|
||||
# See https://ai.google.dev/docs
|
||||
- type: gemini
|
||||
api_base: https://generativelanguage.googleapis.com/v1beta
|
||||
api_key: '{{GEMINI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
auth: null # When set to 'oauth', Coyote will use OAuth instead of an API key
|
||||
# Authenticate with `coyote --authenticate` or `.authenticate` in the REPL
|
||||
api_key: '{{GEMINI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
auth: null # When set to 'oauth', Loki will use OAuth instead of an API key
|
||||
# Authenticate with `loki --authenticate` or `.authenticate` in the REPL
|
||||
patch:
|
||||
chat_completions:
|
||||
'.*':
|
||||
@@ -222,49 +222,49 @@ clients:
|
||||
# See https://docs.anthropic.com/claude/reference/getting-started-with-the-api
|
||||
- type: claude
|
||||
api_base: https://api.anthropic.com/v1 # Optional
|
||||
api_key: '{{ANTHROPIC_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
auth: null # When set to 'oauth', Coyote will use OAuth instead of an API key
|
||||
# Authenticate with `coyote --authenticate` or `.authenticate` in the REPL
|
||||
api_key: '{{ANTHROPIC_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
auth: null # When set to 'oauth', Loki will use OAuth instead of an API key
|
||||
# Authenticate with `loki --authenticate` or `.authenticate` in the REPL
|
||||
|
||||
# See https://docs.mistral.ai/
|
||||
- type: openai-compatible
|
||||
name: mistral
|
||||
api_base: https://api.mistral.ai/v1
|
||||
api_key: '{{MISTRAL_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{MISTRAL_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://docs.x.ai/docs
|
||||
- type: openai-compatible
|
||||
name: xai
|
||||
api_base: https://api.x.ai/v1
|
||||
api_key: '{{XAI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{XAI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://docs.ai21.com/docs/overview
|
||||
- type: openai-compatible
|
||||
name: ai12
|
||||
api_base: https://api.ai21.com/studio/v1
|
||||
api_key: '{{AI21_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{AI21_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://docs.cohere.com/docs/the-cohere-platform
|
||||
- type: cohere
|
||||
api_base: https://api.cohere.ai/v2 # Optional
|
||||
api_key: '{{COHERE_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{COHERE_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://docs.perplexity.ai/getting-started/overview
|
||||
- type: openai-compatible
|
||||
name: perplexity
|
||||
api_base: https://api.perplexity.ai
|
||||
api_key: '{{PERPLEXITY_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{PERPLEXITY_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://console.groq.com/docs/quickstart
|
||||
- type: openai-compatible
|
||||
name: groq
|
||||
api_base: https://api.groq.com/openai/v1
|
||||
api_key: '{{GROQ_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{GROQ_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://learn.microsoft.com/en-us/azure/ai-services/openai/chatgpt-quickstart
|
||||
- type: azure-openai
|
||||
api_base: https://{RESOURCE}.openai.azure.com
|
||||
api_key: '{{AZURE_OPENAI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{AZURE_OPENAI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
models:
|
||||
- name: gpt-4o # Model deployment name
|
||||
max_input_tokens: 128000
|
||||
@@ -295,8 +295,8 @@ clients:
|
||||
|
||||
# See https://docs.aws.amazon.com/bedrock/latest/userguide/
|
||||
- type: bedrock
|
||||
access_key_id: '{{AWS_ACCESS_KEY_ID}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
secret_access_key: '{{AWS_SECRET_ACCESS_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
access_key_id: '{{AWS_ACCESS_KEY_ID}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
secret_access_key: '{{AWS_SECRET_ACCESS_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
region: xxx
|
||||
session_token: xxx # Optional, only needed for temporary credentials
|
||||
|
||||
@@ -304,67 +304,67 @@ clients:
|
||||
- type: openai-compatible
|
||||
name: cloudflare
|
||||
api_base: https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/v1
|
||||
api_key: '{{CLOUDFLARE_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{CLOUDFLARE_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html
|
||||
- type: openai-compatible
|
||||
name: ernie
|
||||
api_base: https://qianfan.baidubce.com/v2
|
||||
api_key: '{{BAIDU_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{BAIDU_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://dashscope.aliyun.com/
|
||||
- type: openai-compatible
|
||||
name: qianwen
|
||||
api_base: https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||
api_key: '{{ALIYUN_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{ALIYUN_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://cloud.tencent.com/product/hunyuan
|
||||
- type: openai-compatible
|
||||
name: hunyuan
|
||||
api_base: https://api.hunyuan.cloud.tencent.com/v1
|
||||
api_key: '{{TENCENT_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{TENCENT_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://platform.moonshot.cn/docs/intro
|
||||
- type: openai-compatible
|
||||
name: moonshot
|
||||
api_base: https://api.moonshot.cn/v1
|
||||
api_key: '{{MOONSHOT_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{MOONSHOT_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://platform.deepseek.com/api-docs/
|
||||
- type: openai-compatible
|
||||
name: deepseek
|
||||
api_base: https://api.deepseek.com
|
||||
api_key: '{{DEEPSEEK_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{DEEPSEEK_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://open.bigmodel.cn/dev/howuse/introduction
|
||||
- type: openai-compatible
|
||||
name: zhipuai
|
||||
api_base: https://open.bigmodel.cn/api/paas/v4
|
||||
api_key: '{{ZHIPUAI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{ZHIPUAI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://platform.minimaxi.com/document/Fast%20access
|
||||
- type: openai-compatible
|
||||
name: minimax
|
||||
api_base: https://api.minimax.chat/v1
|
||||
api_key: '{{MINIMAX_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{MINIMAX_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://openrouter.ai/docs#quick-start
|
||||
- type: openai-compatible
|
||||
name: openrouter
|
||||
api_base: https://openrouter.ai/api/v1
|
||||
api_key: '{{OPENROUTER_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{OPENROUTER_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://github.com/marketplace/models
|
||||
- type: openai-compatible
|
||||
name: github
|
||||
api_base: https://models.inference.ai.azure.com
|
||||
api_key: '{{GITHUB_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{GITHUB_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://deepinfra.com/docs
|
||||
- type: openai-compatible
|
||||
name: deepinfra
|
||||
api_base: https://api.deepinfra.com/v1/openai
|
||||
api_key: '{{DEEPINFRA_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{DEEPINFRA_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
|
||||
# ----- RAG dedicated -----
|
||||
@@ -373,10 +373,10 @@ clients:
|
||||
- type: openai-compatible
|
||||
name: jina
|
||||
api_base: https://api.jina.ai/v1
|
||||
api_key: '{{JINA_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{JINA_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
# See https://docs.voyageai.com/docs/introduction
|
||||
- type: openai-compatible
|
||||
name: voyageai
|
||||
api_base: https://api.voyageai.com/v1
|
||||
api_key: '{{VOYAGEAI_API_KEY}}' # You can either hard-code or inject secrets from the Coyote vault
|
||||
api_key: '{{VOYAGEAI_API_KEY}}' # You can either hard-code or inject secrets from the Loki vault
|
||||
|
||||
@@ -16,7 +16,7 @@ prompt: null # A custom prompt to use for this role tha
|
||||
# The auto-continue system provides built-in task tracking for improved reliability.
|
||||
# When enabled, the model can create todo lists and the system will automatically
|
||||
# prompt it to continue when incomplete tasks remain.
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/coyote/wiki/TODO-System) for more information
|
||||
# See the [Todo System documentation](https://github.com/Dark-Alex-17/loki/wiki/TODO-System) for more information
|
||||
auto_continue: false # Enable automatic continuation when incomplete todos remain (default: false)
|
||||
max_auto_continues: 10 # Maximum number of automatic continuations before stopping (default: 10)
|
||||
inject_todo_instructions: true # Inject default todo tool usage instructions into the system prompt (default: true)
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||
# https://rubydoc.brew.sh/Formula
|
||||
class Coyote < Formula
|
||||
desc "All-in-one, batteries included LLM CLI tool"
|
||||
homepage "https://github.com/Dark-Alex-17/coyote"
|
||||
if OS.mac? and Hardware::CPU.arm?
|
||||
url "https://github.com/Dark-Alex-17/coyote/releases/download/v$version/coyote-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac_arm"
|
||||
elsif OS.mac? and Hardware::CPU.intel?
|
||||
url "https://github.com/Dark-Alex-17/coyote/releases/download/v$version/coyote-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac"
|
||||
else
|
||||
url "https://github.com/Dark-Alex-17/coyote/releases/download/v$version/coyote-x86_64-unknown-linux-musl.tar.gz"
|
||||
sha256 "$hash_linux"
|
||||
end
|
||||
version "$version"
|
||||
license "MIT"
|
||||
|
||||
def install
|
||||
bin.install "coyote"
|
||||
ohai "You're done! Get started with \"coyote --help\""
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
# Documentation: https://docs.brew.sh/Formula-Cookbook
|
||||
# https://rubydoc.brew.sh/Formula
|
||||
class Loki < Formula
|
||||
desc "All-in-one, batteries included LLM CLI tool"
|
||||
homepage "https://github.com/Dark-Alex-17/loki"
|
||||
if OS.mac? and Hardware::CPU.arm?
|
||||
url "https://github.com/Dark-Alex-17/loki/releases/download/v$version/loki-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac_arm"
|
||||
elsif OS.mac? and Hardware::CPU.intel?
|
||||
url "https://github.com/Dark-Alex-17/loki/releases/download/v$version/loki-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "$hash_mac"
|
||||
else
|
||||
url "https://github.com/Dark-Alex-17/loki/releases/download/v$version/loki-x86_64-unknown-linux-musl.tar.gz"
|
||||
sha256 "$hash_linux"
|
||||
end
|
||||
version "$version"
|
||||
license "MIT"
|
||||
|
||||
def install
|
||||
bin.install "loki"
|
||||
ohai "You're done! Get started with \"loki --help\""
|
||||
end
|
||||
end
|
||||
+14
-14
@@ -1,5 +1,5 @@
|
||||
# Graph-based agent definition (full-featured reference)
|
||||
# Location: <coyote-config-dir>/agents/<agent-name>/graph.yaml
|
||||
# Location: <loki-config-dir>/agents/<agent-name>/graph.yaml
|
||||
#
|
||||
# A graph agent is defined by this file alone. An agent directory contains
|
||||
# either a config.yaml (a normal LLM-loop agent) or a graph.yaml (a graph
|
||||
@@ -13,7 +13,7 @@
|
||||
# runnable deep-research graph agent, see assets/agents/deep-research/.
|
||||
#
|
||||
# Full documentation:
|
||||
# https://github.com/Dark-Alex-17/coyote/wiki/Graph-Agents
|
||||
# https://github.com/Dark-Alex-17/loki/wiki/Graph-Agents
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Identity
|
||||
@@ -35,7 +35,7 @@ temperature: 0.0 # Default sampling temperature for `llm` node
|
||||
top_p: null # Default sampling top-p for `llm` nodes
|
||||
|
||||
global_tools: # Tool universe an `llm` node's `tools:` whitelist draws from
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
- fetch_url_via_curl.sh
|
||||
|
||||
mcp_servers: # MCP servers an `llm` node may reference via `mcp:<server>`
|
||||
@@ -52,7 +52,7 @@ conversation_starters: # Suggested prompts surfaced in the UI
|
||||
# (see initial_state below).
|
||||
# - Script nodes via the env var `LLM_AGENT_VAR_<UPPER_NAME>`.
|
||||
# Values may be overridden at runtime with
|
||||
# `coyote -a <agent> --agent-variable <name> <value> "..."`.
|
||||
# `loki -a <agent> --agent-variable <name> <value> "..."`.
|
||||
# ---------------------------------------------------------------------------
|
||||
variables:
|
||||
- name: project_dir
|
||||
@@ -103,7 +103,7 @@ reducers:
|
||||
# Values placed into graph state before any node runs; reference anywhere via
|
||||
# {{key}}.
|
||||
#
|
||||
# Note: `initial_prompt` is seeded automatically by Coyote with the
|
||||
# Note: `initial_prompt` is seeded automatically by Loki with the
|
||||
# caller's prompt. So there's no need to set it here.
|
||||
# ---------------------------------------------------------------------------
|
||||
initial_state:
|
||||
@@ -123,7 +123,7 @@ start: triage # ID of the first node to run (must exist in `nodes
|
||||
# ---------------------------------------------------------------------------
|
||||
# Nodes
|
||||
# Each node is keyed by its id. The `id:` inside a node must match its key
|
||||
# (it may also be omitted and thus Coyote fills it in from the key).
|
||||
# (it may also be omitted and thus Loki fills it in from the key).
|
||||
#
|
||||
# Node types: agent | script | approval | input | llm | rag | map | end
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -202,7 +202,7 @@ nodes:
|
||||
instructions: "You are a web researcher. Cite every claim."
|
||||
prompt: "Web research: {{topic}}. Return findings and sources."
|
||||
tools:
|
||||
- web_search_coyote
|
||||
- web_search_loki
|
||||
- mcp:ddg-search
|
||||
output_schema:
|
||||
type: object
|
||||
@@ -226,13 +226,13 @@ nodes:
|
||||
# The script also receives these env vars (parity with bash tools called
|
||||
# from normal agents):
|
||||
# GRAPH_STATE / GRAPH_STATE_FILE state payload (one of the two is set)
|
||||
# LLM_ROOT_DIR coyote config dir
|
||||
# LLM_ROOT_DIR loki config dir
|
||||
# LLM_PROMPT_UTILS_FILE path to .shared/prompt-utils.sh
|
||||
# LLM_AGENT_DATA_DIR this agent's data directory
|
||||
# LLM_AGENT_VAR_<NAME> one per declared `variables:` entry
|
||||
# PATH with coyote's functions bin dir prepended
|
||||
# PATH with loki's functions bin dir prepended
|
||||
# CLICOLOR_FORCE / FORCE_COLOR so child tools emit ANSI colors
|
||||
# The script's working directory is coyote's invocation CWD (not the agent
|
||||
# The script's working directory is loki's invocation CWD (not the agent
|
||||
# directory), matching the behavior of bash tools.
|
||||
#
|
||||
# This node fires once: after both `retrieve` and `web_search` finish.
|
||||
@@ -256,13 +256,13 @@ nodes:
|
||||
# targets.
|
||||
|
||||
# --- agent node ---------------------------------------------------------
|
||||
# Spawns a full Coyote sub-agent and waits for it. The child uses its own
|
||||
# Spawns a full Loki sub-agent and waits for it. The child uses its own
|
||||
# tool stack. Agent nodes have no `tools:` field. No schema hint is
|
||||
# injected even when `output_schema` is set (unlike llm nodes).
|
||||
deep_dive:
|
||||
id: deep_dive
|
||||
type: agent
|
||||
agent: deep-research # Name of an existing Coyote agent to spawn
|
||||
agent: deep-research # Name of an existing Loki agent to spawn
|
||||
prompt: | # User message sent to the child (templated)
|
||||
Research {{topic}} in depth. Existing context:
|
||||
{{context}}
|
||||
@@ -325,7 +325,7 @@ nodes:
|
||||
instructions: "Research one subject deeply for a {{audience}} audience."
|
||||
prompt: "Research {{subject}}: pull the key facts and one citation."
|
||||
tools:
|
||||
- web_search_coyote
|
||||
- web_search_loki
|
||||
# No `next:`, `state_updates:`, or `output_schema:` here. Map branches
|
||||
# have a strict contract (see `subjects_map.branch` comment).
|
||||
|
||||
@@ -348,7 +348,7 @@ nodes:
|
||||
instructions: "You write concise research summaries for a {{audience}} audience."
|
||||
prompt: "Summarize the topic {{topic}}, using your tools as needed."
|
||||
tools: # Narrow whitelist: exactly these entries, nothing else
|
||||
- web_search_coyote # an exact global-tool / custom-tool name
|
||||
- web_search_loki # an exact global-tool / custom-tool name
|
||||
- mcp:ddg-search # `mcp:<server>` includes that server's functions
|
||||
model: claude:claude-haiku-4-5 # Optional per-node model override
|
||||
temperature: 0.3 # Optional per-node sampling override
|
||||
|
||||
@@ -18,7 +18,7 @@ fmt:
|
||||
cargo fmt --all
|
||||
|
||||
# Build the project for the current system architecture
|
||||
# (Gets stored at ./target/[debug|release]/coyote)
|
||||
# (Gets stored at ./target/[debug|release]/loki)
|
||||
[group: 'build']
|
||||
[arg('build_type', pattern="debug|release")]
|
||||
build build_type='debug':
|
||||
|
||||
Generated
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "coyote",
|
||||
"name": "loki",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<#
|
||||
coyote installer (Windows/PowerShell 5+ and PowerShell 7)
|
||||
loki installer (Windows/PowerShell 5+ and PowerShell 7)
|
||||
|
||||
Examples:
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/scripts/install_coyote.ps1 | iex"
|
||||
pwsh -c "irm https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/scripts/install_coyote.ps1 | iex -Version vX.Y.Z"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "iwr -useb https://raw.githubusercontent.com/Dark-Alex-17/loki/main/scripts/install_loki.ps1 | iex"
|
||||
pwsh -c "irm https://raw.githubusercontent.com/Dark-Alex-17/loki/main/scripts/install_loki.ps1 | iex -Version vX.Y.Z"
|
||||
|
||||
Parameters:
|
||||
-Version <tag> (default: latest)
|
||||
-BinDir <path> (default: %LOCALAPPDATA%\coyote\bin on Windows; ~/.local/bin on *nix PowerShell)
|
||||
-BinDir <path> (default: %LOCALAPPDATA%\loki\bin on Windows; ~/.local/bin on *nix PowerShell)
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$Version = $env:COYOTE_VERSION,
|
||||
[string]$Version = $env:LOKI_VERSION,
|
||||
[string]$BinDir = $env:BIN_DIR
|
||||
)
|
||||
|
||||
$Repo = 'Dark-Alex-17/coyote'
|
||||
$Repo = 'Dark-Alex-17/loki'
|
||||
|
||||
function Write-Info($msg) { Write-Host "[coyote-install] $msg" }
|
||||
function Write-Info($msg) { Write-Host "[loki-install] $msg" }
|
||||
function Fail($msg) { Write-Error $msg; exit 1 }
|
||||
|
||||
Add-Type -AssemblyName System.Runtime
|
||||
@@ -38,7 +38,7 @@ switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) {
|
||||
}
|
||||
|
||||
if (-not $BinDir) {
|
||||
if ($isWin) { $BinDir = Join-Path $env:LOCALAPPDATA 'coyote\bin' }
|
||||
if ($isWin) { $BinDir = Join-Path $env:LOCALAPPDATA 'loki\bin' }
|
||||
else { $home = $env:HOME; if (-not $home) { $home = (Get-Item -Path ~).FullName }; $BinDir = Join-Path $home '.local/bin' }
|
||||
}
|
||||
New-Item -ItemType Directory -Force -Path $BinDir | Out-Null
|
||||
@@ -49,23 +49,23 @@ $apiBase = "https://api.github.com/repos/$Repo/releases"
|
||||
$relUrl = if ($Version) { "$apiBase/tags/$Version" } else { "$apiBase/latest" }
|
||||
Write-Info "Fetching release: $relUrl"
|
||||
try {
|
||||
$release = Invoke-RestMethod -UseBasicParsing -Headers @{ 'User-Agent' = 'coyote-installer' } -Uri $relUrl -Method GET
|
||||
$release = Invoke-RestMethod -UseBasicParsing -Headers @{ 'User-Agent' = 'loki-installer' } -Uri $relUrl -Method GET
|
||||
} catch { Fail "Failed to fetch release metadata. $_" }
|
||||
if (-not $release.assets) { Fail "No assets found in the release." }
|
||||
|
||||
$candidates = @()
|
||||
if ($os -eq 'windows') {
|
||||
if ($arch -eq 'x86_64') { $candidates += 'coyote-x86_64-pc-windows-msvc.zip' }
|
||||
else { $candidates += 'coyote-aarch64-pc-windows-msvc.zip' }
|
||||
if ($arch -eq 'x86_64') { $candidates += 'loki-x86_64-pc-windows-msvc.zip' }
|
||||
else { $candidates += 'loki-aarch64-pc-windows-msvc.zip' }
|
||||
} elseif ($os -eq 'darwin') {
|
||||
if ($arch -eq 'x86_64') { $candidates += 'coyote-x86_64-apple-darwin.tar.gz' }
|
||||
else { $candidates += 'coyote-aarch64-apple-darwin.tar.gz' }
|
||||
if ($arch -eq 'x86_64') { $candidates += 'loki-x86_64-apple-darwin.tar.gz' }
|
||||
else { $candidates += 'loki-aarch64-apple-darwin.tar.gz' }
|
||||
} elseif ($os -eq 'linux') {
|
||||
if ($arch -eq 'x86_64') {
|
||||
$candidates += 'coyote-x86_64-unknown-linux-gnu.tar.gz'
|
||||
$candidates += 'coyote-x86_64-unknown-linux-musl.tar.gz'
|
||||
$candidates += 'loki-x86_64-unknown-linux-gnu.tar.gz'
|
||||
$candidates += 'loki-x86_64-unknown-linux-musl.tar.gz'
|
||||
} else {
|
||||
$candidates += 'coyote-aarch64-unknown-linux-musl.tar.gz'
|
||||
$candidates += 'loki-aarch64-unknown-linux-musl.tar.gz'
|
||||
}
|
||||
} else {
|
||||
Fail "Unsupported OS for this installer: $os"
|
||||
@@ -84,9 +84,9 @@ if (-not $asset) {
|
||||
Write-Info "Selected asset: $($asset.name)"
|
||||
Write-Info "Download URL: $($asset.browser_download_url)"
|
||||
|
||||
$tmp = New-Item -ItemType Directory -Force -Path ([IO.Path]::Combine([IO.Path]::GetTempPath(), "coyote-$(Get-Random)"))
|
||||
$tmp = New-Item -ItemType Directory -Force -Path ([IO.Path]::Combine([IO.Path]::GetTempPath(), "loki-$(Get-Random)"))
|
||||
$archive = Join-Path $tmp.FullName 'asset'
|
||||
try { Invoke-WebRequest -UseBasicParsing -Headers @{ 'User-Agent' = 'coyote-installer' } -Uri $asset.browser_download_url -OutFile $archive } catch { Fail "Failed to download asset. $_" }
|
||||
try { Invoke-WebRequest -UseBasicParsing -Headers @{ 'User-Agent' = 'loki-installer' } -Uri $asset.browser_download_url -OutFile $archive } catch { Fail "Failed to download asset. $_" }
|
||||
|
||||
$extractDir = Join-Path $tmp.FullName 'extract'; New-Item -ItemType Directory -Force -Path $extractDir | Out-Null
|
||||
|
||||
@@ -107,14 +107,14 @@ if ($asset.name -match '\.zip$') {
|
||||
|
||||
$bin = $null
|
||||
Get-ChildItem -Recurse -File $extractDir | ForEach-Object {
|
||||
if ($isWin) { if ($_.Name -ieq 'coyote.exe') { $bin = $_.FullName } }
|
||||
else { if ($_.Name -ieq 'coyote') { $bin = $_.FullName } }
|
||||
if ($isWin) { if ($_.Name -ieq 'loki.exe') { $bin = $_.FullName } }
|
||||
else { if ($_.Name -ieq 'loki') { $bin = $_.FullName } }
|
||||
}
|
||||
if (-not $bin) { Fail "Could not find coyote binary inside the archive." }
|
||||
if (-not $bin) { Fail "Could not find loki binary inside the archive." }
|
||||
|
||||
if (-not $isWin) { try { & chmod +x -- $bin } catch {} }
|
||||
|
||||
$exec = if ($isWin) { 'coyote.exe'} else { 'coyote' }
|
||||
$exec = if ($isWin) { 'loki.exe'} else { 'loki' }
|
||||
$dest = Join-Path $BinDir $exec
|
||||
Copy-Item -Force $bin $dest
|
||||
Write-Info "Installed: $dest"
|
||||
@@ -135,5 +135,5 @@ if ($isWin) {
|
||||
}
|
||||
}
|
||||
|
||||
Write-Info "Done. Try: coyote --help"
|
||||
Write-Info "Done. Try: loki --help"
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# coyote installer (Linux/macOS)
|
||||
# loki installer (Linux/macOS)
|
||||
#
|
||||
# Usage examples:
|
||||
# curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/scripts/install_coyote.sh | bash
|
||||
# curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/coyote/main/scripts/install_coyote.sh | bash -s -- --version vX.Y.Z
|
||||
# BIN_DIR="$HOME/.local/bin" bash scripts/install_coyote.sh
|
||||
# curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/loki/main/scripts/install_loki.sh | bash
|
||||
# curl -fsSL https://raw.githubusercontent.com/Dark-Alex-17/loki/main/scripts/install_loki.sh | bash -s -- --version vX.Y.Z
|
||||
# BIN_DIR="$HOME/.local/bin" bash scripts/install_loki.sh
|
||||
#
|
||||
# Flags / Env:
|
||||
# --version <tag> Release tag (default: latest). Or set COYOTE_VERSION.
|
||||
# --version <tag> Release tag (default: latest). Or set LOKI_VERSION.
|
||||
# --bin-dir <dir> Install directory (default: /usr/local/bin or ~/.local/bin). Or set BIN_DIR.
|
||||
|
||||
REPO="Dark-Alex-17/coyote"
|
||||
VERSION="${COYOTE_VERSION:-}"
|
||||
REPO="Dark-Alex-17/loki"
|
||||
VERSION="${LOKI_VERSION:-}"
|
||||
BIN_DIR="${BIN_DIR:-}"
|
||||
|
||||
usage() {
|
||||
echo "coyote installer (Linux/macOS)"
|
||||
echo "loki installer (Linux/macOS)"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " --version <tag> Release tag (default: latest)"
|
||||
@@ -44,7 +44,7 @@ fi
|
||||
mkdir -p "${BIN_DIR}"
|
||||
|
||||
log() {
|
||||
echo "[coyote-install] $*"
|
||||
echo "[loki-install] $*"
|
||||
}
|
||||
|
||||
need_cmd() {
|
||||
@@ -92,9 +92,9 @@ fi
|
||||
|
||||
http_get() {
|
||||
if [[ "$DL" == "curl" ]]; then
|
||||
curl -fsSL -H 'User-Agent: coyote-installer' "$1"
|
||||
curl -fsSL -H 'User-Agent: loki-installer' "$1"
|
||||
else
|
||||
wget -qO- --header='User-Agent: coyote-installer' "$1"
|
||||
wget -qO- --header='User-Agent: loki-installer' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -111,9 +111,9 @@ fi
|
||||
ASSET_CANDIDATES=()
|
||||
if [[ "$OS" == "darwin" ]]; then
|
||||
if [[ "$ARCH" == "x86_64" ]]; then
|
||||
ASSET_CANDIDATES+=("coyote-x86_64-apple-darwin.tar.gz")
|
||||
ASSET_CANDIDATES+=("loki-x86_64-apple-darwin.tar.gz")
|
||||
else
|
||||
ASSET_CANDIDATES+=("coyote-aarch64-apple-darwin.tar.gz")
|
||||
ASSET_CANDIDATES+=("loki-aarch64-apple-darwin.tar.gz")
|
||||
fi
|
||||
elif [[ "$OS" == "linux" ]]; then
|
||||
if [[ "$ARCH" == "x86_64" ]]; then
|
||||
@@ -122,12 +122,12 @@ elif [[ "$OS" == "linux" ]]; then
|
||||
if ldd --version 2>&1 | grep -qi glibc; then LIBC="gnu"; fi
|
||||
|
||||
if [[ "$LIBC" == "gnu" ]]; then
|
||||
ASSET_CANDIDATES+=("coyote-x86_64-unknown-linux-gnu.tar.gz")
|
||||
ASSET_CANDIDATES+=("loki-x86_64-unknown-linux-gnu.tar.gz")
|
||||
fi
|
||||
|
||||
ASSET_CANDIDATES+=("coyote-x86_64-unknown-linux-musl.tar.gz")
|
||||
ASSET_CANDIDATES+=("loki-x86_64-unknown-linux-musl.tar.gz")
|
||||
else
|
||||
ASSET_CANDIDATES+=("coyote-aarch64-unknown-linux-musl.tar.gz")
|
||||
ASSET_CANDIDATES+=("loki-aarch64-unknown-linux-musl.tar.gz")
|
||||
fi
|
||||
else
|
||||
echo "Error: unsupported OS for this installer: $OS" >&2; exit 1
|
||||
@@ -170,9 +170,9 @@ log "Download URL: $ASSET_URL"
|
||||
|
||||
ARCHIVE="$TMPDIR/asset"
|
||||
if [[ "$DL" == "curl" ]]; then
|
||||
curl -fL -H 'User-Agent: coyote-installer' "$ASSET_URL" -o "$ARCHIVE"
|
||||
curl -fL -H 'User-Agent: loki-installer' "$ASSET_URL" -o "$ARCHIVE"
|
||||
else
|
||||
wget -q --header='User-Agent: coyote-installer' "$ASSET_URL" -O "$ARCHIVE"
|
||||
wget -q --header='User-Agent: loki-installer' "$ASSET_URL" -O "$ARCHIVE"
|
||||
fi
|
||||
|
||||
WORK="$TMPDIR/work"; mkdir -p "$WORK"
|
||||
@@ -192,21 +192,21 @@ fi
|
||||
BIN_PATH=""
|
||||
while IFS= read -r -d '' f; do
|
||||
base=$(basename "$f")
|
||||
if [[ "$base" == "coyote" ]]; then
|
||||
if [[ "$base" == "loki" ]]; then
|
||||
BIN_PATH="$f"
|
||||
break
|
||||
fi
|
||||
done < <(find "$EXTRACTED_DIR" -type f -print0)
|
||||
|
||||
if [[ -z "$BIN_PATH" ]]; then
|
||||
echo "Error: could not find 'coyote' binary in the archive" >&2
|
||||
echo "Error: could not find 'loki' binary in the archive" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod +x "$BIN_PATH"
|
||||
install -m 0755 "$BIN_PATH" "${BIN_DIR}/coyote"
|
||||
install -m 0755 "$BIN_PATH" "${BIN_DIR}/loki"
|
||||
|
||||
log "Installed: ${BIN_DIR}/coyote"
|
||||
log "Installed: ${BIN_DIR}/loki"
|
||||
|
||||
case ":$PATH:" in
|
||||
*":${BIN_DIR}:"*) ;;
|
||||
@@ -216,5 +216,5 @@ case ":$PATH:" in
|
||||
;;
|
||||
esac
|
||||
|
||||
log "Done. Try: coyote --help"
|
||||
log "Done. Try: loki --help"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
_coyote_bash() {
|
||||
_loki_bash() {
|
||||
if [[ -n "$READLINE_LINE" ]]; then
|
||||
READLINE_LINE=$(coyote -e "$READLINE_LINE")
|
||||
READLINE_LINE=$(loki -e "$READLINE_LINE")
|
||||
READLINE_POINT=${#READLINE_LINE}
|
||||
fi
|
||||
}
|
||||
bind -x '"\ee": _coyote_bash'
|
||||
bind -x '"\ee": _loki_bash'
|
||||
@@ -1,7 +1,7 @@
|
||||
fn _coyote_elvish {
|
||||
fn _loki_elvish {
|
||||
var line = (edit:current-command)
|
||||
var new-line = (coyote -e $line)
|
||||
var new-line = (loki -e $line)
|
||||
edit:replace-input $new-line
|
||||
}
|
||||
|
||||
edit:insert:binding[Alt-e] = $_coyote_elvish
|
||||
edit:insert:binding[Alt-e] = $_loki_elvish
|
||||
@@ -1,9 +1,9 @@
|
||||
function _coyote_fish
|
||||
function _loki_fish
|
||||
set -l _old (commandline)
|
||||
if test -n $_old
|
||||
echo -n "⌛"
|
||||
commandline -f repaint
|
||||
commandline (coyote -e $_old)
|
||||
commandline (loki -e $_old)
|
||||
end
|
||||
end
|
||||
bind \ee _coyote_fish
|
||||
bind \ee _loki_fish
|
||||
@@ -1,20 +1,20 @@
|
||||
def _coyote_nushell [] {
|
||||
def _loki_nushell [] {
|
||||
let _prev = (commandline)
|
||||
if ($_prev != "") {
|
||||
print '⌛'
|
||||
commandline edit -r (coyote -e $_prev)
|
||||
commandline edit -r (loki -e $_prev)
|
||||
}
|
||||
}
|
||||
|
||||
$env.config.keybindings = ($env.config.keybindings | append {
|
||||
name: coyote_integration
|
||||
name: loki_integration
|
||||
modifier: alt
|
||||
keycode: char_e
|
||||
mode: [emacs, vi_insert]
|
||||
event:[
|
||||
{
|
||||
send: executehostcommand,
|
||||
cmd: "_coyote_nushell"
|
||||
cmd: "_loki_nushell"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ Set-PSReadLineKeyHandler -Chord "alt+e" -ScriptBlock {
|
||||
[Microsoft.PowerShell.PSConsoleReadline]::GetBufferState([ref]$_old, [ref]$null)
|
||||
if ($_old) {
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Insert('⌛')
|
||||
$_new = (coyote -e $_old)
|
||||
$_new = (loki -e $_old)
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::DeleteLine()
|
||||
[Microsoft.PowerShell.PSConsoleReadline]::Insert($_new)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
_coyote_zsh() {
|
||||
_loki_zsh() {
|
||||
if [[ -n "$BUFFER" ]]; then
|
||||
local _old=$BUFFER
|
||||
BUFFER+="⌛"
|
||||
zle -I && zle redisplay
|
||||
BUFFER=$(coyote -e "$_old")
|
||||
BUFFER=$(loki -e "$_old")
|
||||
zle end-of-line
|
||||
fi
|
||||
}
|
||||
zle -N _coyote_zsh
|
||||
bindkey '\ee' _coyote_zsh
|
||||
zle -N _loki_zsh
|
||||
bindkey '\ee' _loki_zsh
|
||||
@@ -9,7 +9,7 @@ use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::io;
|
||||
|
||||
const COYOTE_CLI_NAME: &str = "coyote";
|
||||
const LOKI_CLI_NAME: &str = "loki";
|
||||
|
||||
#[derive(Clone, Copy, Debug, clap::ValueEnum)]
|
||||
pub enum ShellCompletion {
|
||||
@@ -24,14 +24,12 @@ pub enum ShellCompletion {
|
||||
impl ShellCompletion {
|
||||
pub fn generate_completions(self, cmd: &mut clap::Command) {
|
||||
match self {
|
||||
Self::Bash => generate(Shell::Bash, cmd, COYOTE_CLI_NAME, &mut io::stdout()),
|
||||
Self::Elvish => generate(Shell::Elvish, cmd, COYOTE_CLI_NAME, &mut io::stdout()),
|
||||
Self::Fish => generate(Shell::Fish, cmd, COYOTE_CLI_NAME, &mut io::stdout()),
|
||||
Self::PowerShell => {
|
||||
generate(Shell::PowerShell, cmd, COYOTE_CLI_NAME, &mut io::stdout())
|
||||
}
|
||||
Self::Zsh => generate(Shell::Zsh, cmd, COYOTE_CLI_NAME, &mut io::stdout()),
|
||||
Self::Nushell => generate(Nushell, cmd, COYOTE_CLI_NAME, &mut io::stdout()),
|
||||
Self::Bash => generate(Shell::Bash, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
Self::Elvish => generate(Shell::Elvish, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
Self::Fish => generate(Shell::Fish, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
Self::PowerShell => generate(Shell::PowerShell, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
Self::Zsh => generate(Shell::Zsh, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
Self::Nushell => generate(Nushell, cmd, LOKI_CLI_NAME, &mut io::stdout()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -15,7 +15,7 @@ use std::io::{Read, stdin};
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[command(
|
||||
name = "coyote",
|
||||
name = "loki",
|
||||
author = crate_authors!(),
|
||||
version = crate_version!(),
|
||||
about = crate_description!(),
|
||||
@@ -125,19 +125,19 @@ pub struct Cli {
|
||||
/// Disable colored log output
|
||||
#[arg(long, requires = "tail_logs")]
|
||||
pub disable_log_colors: bool,
|
||||
/// Add a secret to the Coyote vault
|
||||
/// Add a secret to the Loki vault
|
||||
#[arg(long, value_name = "SECRET_NAME", exclusive = true)]
|
||||
pub add_secret: Option<String>,
|
||||
/// Decrypt a secret from the Coyote vault and print the plaintext
|
||||
/// Decrypt a secret from the Loki vault and print the plaintext
|
||||
#[arg(long, value_name = "SECRET_NAME", exclusive = true, add = ArgValueCompleter::new(secrets_completer))]
|
||||
pub get_secret: Option<String>,
|
||||
/// Update an existing secret in the Coyote vault
|
||||
/// Update an existing secret in the Loki vault
|
||||
#[arg(long, value_name = "SECRET_NAME", exclusive = true, add = ArgValueCompleter::new(secrets_completer))]
|
||||
pub update_secret: Option<String>,
|
||||
/// Delete a secret from the Coyote vault
|
||||
/// Delete a secret from the Loki vault
|
||||
#[arg(long, value_name = "SECRET_NAME", exclusive = true, add = ArgValueCompleter::new(secrets_completer))]
|
||||
pub delete_secret: Option<String>,
|
||||
/// List all secrets stored in the Coyote vault
|
||||
/// List all secrets stored in the Loki vault
|
||||
#[arg(long, exclusive = true)]
|
||||
pub list_secrets: bool,
|
||||
/// Authenticate with an LLM provider using OAuth (e.g., --authenticate client_name)
|
||||
@@ -146,10 +146,10 @@ pub struct Cli {
|
||||
/// Generate static shell completion scripts
|
||||
#[arg(long, value_name = "SHELL", value_enum)]
|
||||
pub completions: Option<ShellCompletion>,
|
||||
/// Update Coyote to the latest release, or to a specific version
|
||||
/// Update Loki to the latest release, or to a specific version
|
||||
#[arg(long, value_name = "VERSION")]
|
||||
pub update: Option<Option<String>>,
|
||||
/// With --update, update even if Coyote was installed via a package manager
|
||||
/// With --update, update even if Loki was installed via a package manager
|
||||
#[arg(long, requires = "update")]
|
||||
pub force: bool,
|
||||
}
|
||||
@@ -202,7 +202,7 @@ mod tests {
|
||||
use clap::Parser;
|
||||
|
||||
fn parse(args: &[&str]) -> Cli {
|
||||
let mut full_args = vec!["coyote"];
|
||||
let mut full_args = vec!["loki"];
|
||||
full_args.extend_from_slice(args);
|
||||
Cli::try_parse_from(full_args).unwrap()
|
||||
}
|
||||
@@ -436,6 +436,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_force_without_update_fails() {
|
||||
assert!(Cli::try_parse_from(["coyote", "--force"]).is_err());
|
||||
assert!(Cli::try_parse_from(["loki", "--force"]).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
+30
-24
@@ -85,7 +85,7 @@ async fn prepare_chat_completions(
|
||||
let ready = oauth::prepare_oauth_access_token(client, &provider, self_.name()).await?;
|
||||
if !ready {
|
||||
bail!(
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'coyote --authenticate {}' or '.authenticate' in the REPL",
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'loki --authenticate {}' or '.authenticate' in the REPL",
|
||||
self_.name(),
|
||||
self_.name()
|
||||
);
|
||||
@@ -100,7 +100,7 @@ async fn prepare_chat_completions(
|
||||
request_data.header("x-api-key", api_key);
|
||||
} else {
|
||||
bail!(
|
||||
"No authentication configured for '{}'. Set `api_key` or use `auth: oauth` with `coyote --authenticate {}`.",
|
||||
"No authentication configured for '{}'. Set `api_key` or use `auth: oauth` with `loki --authenticate {}`.",
|
||||
self_.name(),
|
||||
self_.name()
|
||||
);
|
||||
@@ -114,35 +114,41 @@ async fn prepare_chat_completions(
|
||||
///
|
||||
/// This behavior was discovered 2026-03-17.
|
||||
///
|
||||
/// The prefix must be in its **own** top-level system block. Concatenating it
|
||||
/// with role / session content into a single block causes Anthropic to reject
|
||||
/// the request with `rate_limit_error`. Any pre-existing system content is
|
||||
/// preserved as additional blocks after the prefix.
|
||||
/// So this function injects the Claude Code system prompt into the request
|
||||
/// body to make it a valid request.
|
||||
fn inject_oauth_system_prompt(body: &mut Value) {
|
||||
let existing_blocks: Vec<Value> = match body.get("system") {
|
||||
let existing_text = match body.get("system") {
|
||||
Some(Value::String(s)) => {
|
||||
if s.is_empty() {
|
||||
Vec::new()
|
||||
} else {
|
||||
vec![json!({ "type": "text", "text": s })]
|
||||
if s.starts_with(CLAUDE_CODE_PREFIX) {
|
||||
return;
|
||||
}
|
||||
(!s.is_empty()).then(|| s.clone())
|
||||
}
|
||||
Some(Value::Array(blocks)) => blocks.clone(),
|
||||
_ => Vec::new(),
|
||||
Some(Value::Array(blocks)) => {
|
||||
let already_injected = blocks.iter().any(|b| {
|
||||
b.get("text")
|
||||
.and_then(|t| t.as_str())
|
||||
.map(|t| t.starts_with(CLAUDE_CODE_PREFIX))
|
||||
.unwrap_or(false)
|
||||
});
|
||||
if already_injected {
|
||||
return;
|
||||
}
|
||||
let joined: Vec<String> = blocks
|
||||
.iter()
|
||||
.filter_map(|b| b.get("text").and_then(|t| t.as_str()).map(String::from))
|
||||
.collect();
|
||||
(!joined.is_empty()).then(|| joined.join("\n\n"))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let already_injected = existing_blocks
|
||||
.first()
|
||||
.and_then(|b| b.get("text").and_then(|t| t.as_str()))
|
||||
.map(|t| t == CLAUDE_CODE_PREFIX)
|
||||
.unwrap_or(false);
|
||||
if already_injected {
|
||||
return;
|
||||
}
|
||||
let merged = match existing_text {
|
||||
Some(rest) => format!("{}\n\n{}", CLAUDE_CODE_PREFIX, rest),
|
||||
None => CLAUDE_CODE_PREFIX.to_string(),
|
||||
};
|
||||
|
||||
let mut system = vec![json!({ "type": "text", "text": CLAUDE_CODE_PREFIX })];
|
||||
system.extend(existing_blocks);
|
||||
body["system"] = Value::Array(system);
|
||||
body["system"] = json!([{ "type": "text", "text": merged }]);
|
||||
}
|
||||
|
||||
pub async fn claude_chat_completions(
|
||||
|
||||
@@ -111,7 +111,7 @@ async fn prepare_chat_completions(
|
||||
let ready = oauth::prepare_oauth_access_token(client, &provider, self_.name()).await?;
|
||||
if !ready {
|
||||
bail!(
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'coyote --authenticate {}' or '.authenticate' in the REPL",
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'loki --authenticate {}' or '.authenticate' in the REPL",
|
||||
self_.name(),
|
||||
self_.name()
|
||||
);
|
||||
@@ -122,7 +122,7 @@ async fn prepare_chat_completions(
|
||||
request_data.header("x-goog-api-key", api_key);
|
||||
} else {
|
||||
bail!(
|
||||
"No authentication configured for '{}'. Set `api_key` or use `auth: oauth` with `coyote --authenticate {}`.",
|
||||
"No authentication configured for '{}'. Set `api_key` or use `auth: oauth` with `loki --authenticate {}`.",
|
||||
self_.name(),
|
||||
self_.name()
|
||||
);
|
||||
@@ -181,7 +181,7 @@ async fn prepare_embeddings(
|
||||
let ready = oauth::prepare_oauth_access_token(client, &provider, self_.name()).await?;
|
||||
if !ready {
|
||||
bail!(
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'coyote --authenticate {}' or '.authenticate' in the REPL",
|
||||
"OAuth configured but no tokens found for '{}'. Run: 'loki --authenticate {}' or '.authenticate' in the REPL",
|
||||
self_.name(),
|
||||
self_.name()
|
||||
);
|
||||
|
||||
+1
-1
@@ -526,7 +526,7 @@ impl RoleLike for Agent {
|
||||
}
|
||||
|
||||
fn enabled_tools(&self) -> Option<String> {
|
||||
None
|
||||
self.config.global_tools.clone().join(",").into()
|
||||
}
|
||||
|
||||
fn enabled_mcp_servers(&self) -> Option<String> {
|
||||
|
||||
+2
-2
@@ -879,7 +879,7 @@ mod tests {
|
||||
#[test]
|
||||
fn from_files_loads_single_text_file() {
|
||||
let dir = env::temp_dir().join(format!(
|
||||
"coyote-input-test-{}",
|
||||
"loki-input-test-{}",
|
||||
SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
@@ -906,7 +906,7 @@ mod tests {
|
||||
#[test]
|
||||
fn from_files_loads_multiple_files() {
|
||||
let dir = env::temp_dir().join(format!(
|
||||
"coyote-input-test-multi-{}",
|
||||
"loki-input-test-multi-{}",
|
||||
SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
|
||||
@@ -136,7 +136,7 @@ impl Drop for TempRepoDir {
|
||||
}
|
||||
|
||||
fn clone_to_temp(url: &str, reference: Option<&str>) -> Result<TempRepoDir> {
|
||||
let dest = utils::temp_file("coyote-remote-install-", "");
|
||||
let dest = utils::temp_file("loki-remote-install-", "");
|
||||
let dest_arg: OsString = dest.as_os_str().into();
|
||||
|
||||
let is_sha = reference
|
||||
@@ -875,7 +875,7 @@ fn print_secret_summary(added: &[String], deferred: &[String]) {
|
||||
if !deferred.is_empty() {
|
||||
println!(
|
||||
"\nThe following secrets are still required by your MCP servers. \
|
||||
Add them with `coyote --add-secret <NAME>` or `.vault add <NAME>` in the REPL:"
|
||||
Add them with `loki --add-secret <NAME>` or `.vault add <NAME>` in the REPL:"
|
||||
);
|
||||
for name in deferred {
|
||||
println!(" {{{{ {name} }}}}");
|
||||
@@ -1265,12 +1265,12 @@ mod tests {
|
||||
let target = dir.join("target.json");
|
||||
write_mcp(
|
||||
&remote,
|
||||
r#"{"mcpServers": {"x": {"type":"stdio","command":"echo","env":{"K":"{{COYOTE_TEST_MERGE_SECRET}}"}}}}"#,
|
||||
r#"{"mcpServers": {"x": {"type":"stdio","command":"echo","env":{"K":"{{LOKI_TEST_MERGE_SECRET}}"}}}}"#,
|
||||
);
|
||||
|
||||
let report = merge_mcp_json(None, &remote, &target, false).unwrap();
|
||||
|
||||
assert_eq!(report.missing_secrets, vec!["COYOTE_TEST_MERGE_SECRET"]);
|
||||
assert_eq!(report.missing_secrets, vec!["LOKI_TEST_MERGE_SECRET"]);
|
||||
let _ = fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
@@ -1300,8 +1300,8 @@ mod tests {
|
||||
#[test]
|
||||
fn handle_missing_secrets_defers_all_in_non_tty() {
|
||||
let missing = vec![
|
||||
"COYOTE_TEST_STEP4_A".to_string(),
|
||||
"COYOTE_TEST_STEP4_B".to_string(),
|
||||
"LOKI_TEST_STEP4_A".to_string(),
|
||||
"LOKI_TEST_STEP4_B".to_string(),
|
||||
];
|
||||
|
||||
assert!(handle_missing_secrets(&missing).is_ok());
|
||||
|
||||
+3
-3
@@ -104,13 +104,13 @@ const DEFAULT_VISIBLE_TOOLS: [&str; 18] = [
|
||||
"get_current_weather.sh",
|
||||
"search_wikipedia.sh",
|
||||
"search_arxiv.sh",
|
||||
"web_search_coyote.sh",
|
||||
"web_search_loki.sh",
|
||||
];
|
||||
|
||||
const CLIENTS_FIELD: &str = "clients";
|
||||
|
||||
const SYNC_MODELS_URL: &str =
|
||||
"https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml";
|
||||
"https://raw.githubusercontent.com/Dark-Alex-17/loki/refs/heads/main/models.yaml";
|
||||
|
||||
const SUMMARIZATION_PROMPT: &str =
|
||||
"Summarize the discussion briefly in 200 words or less to use as a prompt for future context.";
|
||||
@@ -625,7 +625,7 @@ pub async fn create_config_file(config_path: &Path) -> Result<()> {
|
||||
|
||||
let config_data = serde_yaml::to_string(&config).with_context(|| "Failed to create config")?;
|
||||
let config_data = format!(
|
||||
"# see https://github.com/Dark-Alex-17/coyote/blob/main/config.example.yaml\n\n{config_data}"
|
||||
"# see https://github.com/Dark-Alex-17/loki/blob/main/config.example.yaml\n\n{config_data}"
|
||||
);
|
||||
|
||||
ensure_parent_exists(config_path)?;
|
||||
|
||||
@@ -1498,7 +1498,7 @@ impl RequestContext {
|
||||
if !target_path.exists() {
|
||||
fs::write(
|
||||
&target_path,
|
||||
"# see https://github.com/Dark-Alex-17/coyote/blob/main/config.agent.example.yaml\n",
|
||||
"# see https://github.com/Dark-Alex-17/loki/blob/main/config.agent.example.yaml\n",
|
||||
)
|
||||
.with_context(|| format!("Failed to write to '{}'", target_path.display()))?;
|
||||
}
|
||||
@@ -2706,7 +2706,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let path = env::temp_dir().join(format!("coyote-request-context-tests-{unique}"));
|
||||
let path = env::temp_dir().join(format!("loki-request-context-tests-{unique}"));
|
||||
create_dir_all(&path).unwrap();
|
||||
unsafe {
|
||||
env::set_var(&key, &path);
|
||||
@@ -2969,7 +2969,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_mcp_disabled_skips_servers() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(false, &["github", "slack"]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
|
||||
let app = ctx.app.config.clone();
|
||||
@@ -2983,7 +2982,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_no_enabled_servers_yields_empty_runtime() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(true, &["github"]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
|
||||
let app = ctx.app.config.clone();
|
||||
@@ -2997,7 +2995,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_no_mcp_config_yields_empty_runtime() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(true, &[]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
|
||||
let app = ctx.app.config.clone();
|
||||
@@ -3011,7 +3008,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_preserves_tool_tracker() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(false, &[]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
|
||||
let dummy = ToolCall {
|
||||
@@ -3039,7 +3035,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_repl_mode_appends_user_interaction_functions() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(false, &[]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Repl);
|
||||
let app = ctx.app.config.clone();
|
||||
@@ -3063,7 +3058,6 @@ mod tests {
|
||||
#[test]
|
||||
#[serial]
|
||||
fn rebuild_tool_scope_cmd_mode_no_user_interaction_functions() {
|
||||
let _guard = TestConfigDirGuard::new();
|
||||
let app_state = app_state_with_mcp_config(false, &[]);
|
||||
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
|
||||
let app = ctx.app.config.clone();
|
||||
|
||||
+17
-17
@@ -69,7 +69,7 @@ fn normalize_version(requested: Option<String>) -> Option<String> {
|
||||
}
|
||||
|
||||
fn is_dir_writable(dir: &Path) -> bool {
|
||||
let probe = dir.join(format!(".coyote-update-write-test-{}", process::id()));
|
||||
let probe = dir.join(format!(".loki-update-write-test-{}", process::id()));
|
||||
match OpenOptions::new().write(true).create_new(true).open(&probe) {
|
||||
Ok(_) => {
|
||||
let _ = fs::remove_file(&probe);
|
||||
@@ -83,24 +83,24 @@ pub fn run_self_update(requested: Option<String>, force: bool) -> Result<()> {
|
||||
let target_tag = normalize_version(requested);
|
||||
|
||||
let exe_path = env::current_exe()
|
||||
.context("Could not determine the path of the running coyote executable")?;
|
||||
.context("Could not determine the path of the running loki executable")?;
|
||||
let resolved = canonicalize(&exe_path).unwrap_or_else(|_| exe_path.clone());
|
||||
let source = classify_install_path(&resolved);
|
||||
|
||||
if source.is_package_managed() {
|
||||
let body = match source {
|
||||
InstallSource::Homebrew => format!(
|
||||
"Coyote appears to be installed via Homebrew ({}).\n\
|
||||
"Loki appears to be installed via Homebrew ({}).\n\
|
||||
Updating in place replaces the binary inside Homebrew's Cellar; `brew` will\n\
|
||||
then report a version that no longer matches the file on disk, and a later\n\
|
||||
`brew upgrade`/`brew reinstall` may overwrite it or fail.\n\
|
||||
The clean way to update is: brew upgrade coyote",
|
||||
The clean way to update is: brew upgrade loki",
|
||||
exe_path.display()
|
||||
),
|
||||
InstallSource::Cargo => format!(
|
||||
"Coyote appears to be installed via `cargo install` ({}).\n\
|
||||
"Loki appears to be installed via `cargo install` ({}).\n\
|
||||
Updating in place leaves Cargo's records out of sync with the binary on disk.\n\
|
||||
The clean way to update is: cargo install --locked coyote-ai",
|
||||
The clean way to update is: cargo install --locked loki-ai",
|
||||
exe_path.display()
|
||||
),
|
||||
InstallSource::Manual => unreachable!("Manual installs are not package-managed"),
|
||||
@@ -130,7 +130,7 @@ pub fn run_self_update(requested: Option<String>, force: bool) -> Result<()> {
|
||||
{
|
||||
bail!(
|
||||
"No write permission for '{}'. Re-run with elevated permissions (e.g. sudo), \
|
||||
or update Coyote through your package manager.",
|
||||
or update Loki through your package manager.",
|
||||
parent.display()
|
||||
);
|
||||
}
|
||||
@@ -139,8 +139,8 @@ pub fn run_self_update(requested: Option<String>, force: bool) -> Result<()> {
|
||||
let mut builder = Update::configure();
|
||||
builder
|
||||
.repo_owner("Dark-Alex-17")
|
||||
.repo_name("coyote")
|
||||
.bin_name("coyote")
|
||||
.repo_name("loki")
|
||||
.bin_name("loki")
|
||||
.current_version(env!("CARGO_PKG_VERSION"))
|
||||
.no_confirm(true)
|
||||
.show_download_progress(interactive);
|
||||
@@ -155,10 +155,10 @@ pub fn run_self_update(requested: Option<String>, force: bool) -> Result<()> {
|
||||
|
||||
match status {
|
||||
Status::UpToDate(version) => {
|
||||
println!("Coyote is already up to date (v{version}).");
|
||||
println!("Loki is already up to date (v{version}).");
|
||||
}
|
||||
Status::Updated(version) => {
|
||||
println!("Coyote updated to v{version}. Restart coyote to use the new version.");
|
||||
println!("Loki updated to v{version}. Restart loki to use the new version.");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -172,7 +172,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_cargo_install() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/home/u/.cargo/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/home/u/.cargo/bin/loki")),
|
||||
InstallSource::Cargo
|
||||
);
|
||||
}
|
||||
@@ -180,7 +180,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_homebrew_opt_prefix() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/opt/homebrew/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/opt/homebrew/bin/loki")),
|
||||
InstallSource::Homebrew
|
||||
);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_homebrew_cellar() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/usr/local/Cellar/coyote/0.3.0/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/usr/local/Cellar/loki/0.3.0/bin/loki")),
|
||||
InstallSource::Homebrew
|
||||
);
|
||||
}
|
||||
@@ -196,7 +196,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_homebrew_linuxbrew() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/home/linuxbrew/.linuxbrew/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/home/linuxbrew/.linuxbrew/bin/loki")),
|
||||
InstallSource::Homebrew
|
||||
);
|
||||
}
|
||||
@@ -204,7 +204,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_manual_usr_local_bin() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/usr/local/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/usr/local/bin/loki")),
|
||||
InstallSource::Manual
|
||||
);
|
||||
}
|
||||
@@ -212,7 +212,7 @@ mod tests {
|
||||
#[test]
|
||||
fn classify_manual_local_bin() {
|
||||
assert_eq!(
|
||||
classify_install_path(&PathBuf::from("/home/u/.local/bin/coyote")),
|
||||
classify_install_path(&PathBuf::from("/home/u/.local/bin/loki")),
|
||||
InstallSource::Manual
|
||||
);
|
||||
}
|
||||
|
||||
+5
-27
@@ -4,7 +4,6 @@ pub(crate) mod user_interaction;
|
||||
|
||||
use crate::{
|
||||
config::{Agent, RequestContext},
|
||||
graph,
|
||||
utils::*,
|
||||
};
|
||||
|
||||
@@ -1200,9 +1199,6 @@ pub fn run_llm_function(
|
||||
if dir.exists() {
|
||||
bin_dirs.push(dir);
|
||||
}
|
||||
if graph::agent_has_graph(&agent_name) {
|
||||
envs.insert("AUTO_CONFIRM".into(), "true".into());
|
||||
}
|
||||
} else {
|
||||
bin_dirs.push(paths::functions_bin_dir());
|
||||
}
|
||||
@@ -1246,7 +1242,7 @@ pub fn run_llm_function(
|
||||
.map_err(|err| anyhow!("Unable to run {command_name}, {err}"))?;
|
||||
|
||||
let stdout = child.stdout.take().expect("Failed to capture stdout");
|
||||
let stderr = child.stderr.take().expect("Failed to capture stderr");
|
||||
let mut stderr = child.stderr.take().expect("Failed to capture stderr");
|
||||
|
||||
let stdout_thread = std::thread::spawn(move || {
|
||||
let mut buffer = [0; 1024];
|
||||
@@ -1273,29 +1269,8 @@ pub fn run_llm_function(
|
||||
});
|
||||
|
||||
let stderr_thread = std::thread::spawn(move || {
|
||||
let mut buffer = [0; 1024];
|
||||
let mut reader = stderr;
|
||||
let mut err = io::stderr();
|
||||
let mut buf = Vec::new();
|
||||
while let Ok(n) = reader.read(&mut buffer) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
let chunk = &buffer[0..n];
|
||||
buf.extend_from_slice(chunk);
|
||||
let mut last_pos = 0;
|
||||
for (i, &byte) in chunk.iter().enumerate() {
|
||||
if byte == b'\n' {
|
||||
let _ = err.write_all(&chunk[last_pos..i]);
|
||||
let _ = err.write_all(b"\r\n");
|
||||
last_pos = i + 1;
|
||||
}
|
||||
}
|
||||
if last_pos < n {
|
||||
let _ = err.write_all(&chunk[last_pos..n]);
|
||||
}
|
||||
let _ = err.flush();
|
||||
}
|
||||
let _ = stderr.read_to_end(&mut buf);
|
||||
buf
|
||||
});
|
||||
|
||||
@@ -1308,6 +1283,9 @@ pub fn run_llm_function(
|
||||
let exit_code = status.code().unwrap_or_default();
|
||||
if exit_code != 0 {
|
||||
let stderr = String::from_utf8_lossy(&stderr_bytes).trim().to_string();
|
||||
if !stderr.is_empty() {
|
||||
eprintln!("{stderr}");
|
||||
}
|
||||
let tool_error_message = format!("Tool call '{command_name}' exited with code {exit_code}");
|
||||
eprintln!("{}", warning_text(&format!("⚠️ {tool_error_message} ⚠️")));
|
||||
let mut error_json = json!({"tool_call_error": tool_error_message});
|
||||
|
||||
+2
-2
@@ -568,13 +568,13 @@ mod tests {
|
||||
let entries = vec![
|
||||
"read_query".to_string(),
|
||||
"mcp:pubmed-search".to_string(),
|
||||
"web_search_coyote".to_string(),
|
||||
"web_search_loki".to_string(),
|
||||
"mcp:github".to_string(),
|
||||
];
|
||||
|
||||
let (regular, mcp) = categorize_tools(Some(&entries));
|
||||
|
||||
assert_eq!(regular, vec!["read_query", "web_search_coyote"]);
|
||||
assert_eq!(regular, vec!["read_query", "web_search_loki"]);
|
||||
assert_eq!(mcp, vec!["pubmed-search", "github"]);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -423,7 +423,7 @@ mod tests {
|
||||
#[test]
|
||||
fn load_from_file_reads_disk() {
|
||||
let dir = env::temp_dir();
|
||||
let path = dir.join(format!("coyote_graph_parser_test_{}.yaml", process::id()));
|
||||
let path = dir.join(format!("loki_graph_parser_test_{}.yaml", process::id()));
|
||||
let yaml = formatdoc! {r#"
|
||||
name: disk_graph
|
||||
version: "1.0"
|
||||
|
||||
@@ -55,7 +55,6 @@ impl ScriptExecutor {
|
||||
cmd.stdout(Stdio::piped());
|
||||
cmd.stderr(Stdio::piped());
|
||||
cmd.envs(&self.extra_envs);
|
||||
cmd.env("AUTO_CONFIRM", "true");
|
||||
match &state_repr {
|
||||
StateRepresentation::Inline(json) => {
|
||||
cmd.env("GRAPH_STATE", json);
|
||||
|
||||
+2
-2
@@ -812,7 +812,7 @@ model: anthropic:claude-sonnet-4-6
|
||||
temperature: 0.2
|
||||
top_p: 0.9
|
||||
global_tools:
|
||||
- web_search_coyote.sh
|
||||
- web_search_loki.sh
|
||||
mcp_servers:
|
||||
- pubmed-search
|
||||
conversation_starters:
|
||||
@@ -827,7 +827,7 @@ nodes:
|
||||
assert_eq!(graph.model.as_deref(), Some("anthropic:claude-sonnet-4-6"));
|
||||
assert_eq!(graph.temperature, Some(0.2));
|
||||
assert_eq!(graph.top_p, Some(0.9));
|
||||
assert_eq!(graph.global_tools, vec!["web_search_coyote.sh"]);
|
||||
assert_eq!(graph.global_tools, vec!["web_search_loki.sh"]);
|
||||
assert_eq!(graph.mcp_servers, vec!["pubmed-search"]);
|
||||
assert_eq!(graph.conversation_starters, vec!["Look up 2160-0"]);
|
||||
}
|
||||
|
||||
@@ -369,8 +369,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("time went backwards")
|
||||
.as_nanos();
|
||||
let path =
|
||||
std::env::temp_dir().join(format!("coyote_python_parser_{file_name}_{unique}.py"));
|
||||
let path = std::env::temp_dir().join(format!("loki_python_parser_{file_name}_{unique}.py"));
|
||||
fs::write(&path, source).expect("failed to write temp python source");
|
||||
let file = File::open(&path).expect("failed to open temp python source");
|
||||
let result = generate_python_declarations(file, file_name, Some(parent));
|
||||
|
||||
@@ -425,7 +425,7 @@ mod tests {
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("time")
|
||||
.as_nanos();
|
||||
let path = std::env::temp_dir().join(format!("coyote_ts_parser_{file_name}_{unique}.ts"));
|
||||
let path = std::env::temp_dir().join(format!("loki_ts_parser_{file_name}_{unique}.ts"));
|
||||
fs::write(&path, source).expect("write");
|
||||
let file = File::open(&path).expect("open");
|
||||
let result = generate_typescript_declarations(file, file_name, Some(parent));
|
||||
|
||||
+2
-2
@@ -215,7 +215,7 @@ static REPL_COMMANDS: LazyLock<[ReplCommand; 42]> = LazyLock::new(|| {
|
||||
),
|
||||
ReplCommand::new(
|
||||
".vault",
|
||||
"View or modify the Coyote vault",
|
||||
"View or modify the Loki vault",
|
||||
AssertState::pass(),
|
||||
),
|
||||
ReplCommand::new(
|
||||
@@ -225,7 +225,7 @@ static REPL_COMMANDS: LazyLock<[ReplCommand; 42]> = LazyLock::new(|| {
|
||||
),
|
||||
ReplCommand::new(
|
||||
".update",
|
||||
"Update Coyote to the latest release (or a specified version)",
|
||||
"Update Loki to the latest release (or a specified version)",
|
||||
AssertState::pass(),
|
||||
),
|
||||
ReplCommand::new(".exit", "Exit REPL", AssertState::pass()),
|
||||
|
||||
+1
-1
@@ -366,7 +366,7 @@ mod tests {
|
||||
assert!(is_valid_extension(Some(&md_ext), Path::new("Agents.md")));
|
||||
assert!(is_valid_extension(
|
||||
Some(&md_ext),
|
||||
Path::new("/home/atusa/code/coyote.wiki/Agents.md")
|
||||
Path::new("/home/atusa/code/loki.wiki/Agents.md")
|
||||
));
|
||||
assert!(!is_valid_extension(Some(&md_ext), Path::new("notes.txt")));
|
||||
assert!(!is_valid_extension(Some(&md_ext), Path::new("README")));
|
||||
|
||||
+2
-2
@@ -28,7 +28,7 @@ pub fn ensure_password_file_initialized(local_provider: &mut LocalProvider) -> R
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"A password file is required to utilize the Coyote vault. Please configure a password file in your config file and try again."
|
||||
"A password file is required to utilize the Loki vault. Please configure a password file in your config file and try again."
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ pub fn create_vault_password_file(vault: &mut Vault) -> Result<()> {
|
||||
|
||||
if !ans {
|
||||
return Err(anyhow!(
|
||||
"A password file is required to utilize the Coyote vault. Please configure a password file in your config file and try again."
|
||||
"A password file is required to utilize the Loki vault. Please configure a password file in your config file and try again."
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user