aigency 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/README.md +12 -13
- data/lib/aigency/aigent/current_time.rb +33 -0
- data/lib/aigency/aigent/shell.rb +108 -0
- data/lib/aigency/aigent.rb +117 -65
- data/lib/aigency/delegator.rb +11 -0
- data/lib/aigency/plugin/shell.rb +11 -0
- data/lib/aigency/plugin.rb +39 -0
- data/lib/aigency/rake.rb +13 -0
- data/lib/aigency/sandbox/exec.rb +21 -0
- data/lib/aigency/sandbox.rb +22 -0
- data/lib/aigency/shell.rb +5 -5
- data/lib/aigency/tempdir/helpers.rb +15 -0
- data/lib/aigency/tempdir/list.rb +17 -0
- data/lib/aigency/tempdir/read.rb +32 -0
- data/lib/aigency/tempdir/size.rb +27 -0
- data/lib/aigency/tempdir/write.rb +28 -0
- data/lib/aigency/tempdir.rb +19 -0
- data/lib/aigency/tool.rb +5 -0
- data/lib/aigency/usability.rb +1 -0
- data/lib/aigency/version.rb +1 -1
- data/lib/aigency/workspace/cat.rb +11 -0
- data/lib/aigency/workspace/cmd.rb +59 -0
- data/lib/aigency/workspace/copy_tempdir_file.rb +28 -0
- data/lib/aigency/workspace/cp.rb +11 -0
- data/lib/aigency/workspace/diff.rb +11 -0
- data/lib/aigency/workspace/grep.rb +15 -0
- data/lib/aigency/workspace/head.rb +11 -0
- data/lib/aigency/workspace/helpers.rb +40 -3
- data/lib/aigency/workspace/ls.rb +11 -0
- data/lib/aigency/workspace/mkdir.rb +11 -0
- data/lib/aigency/workspace/mv.rb +11 -0
- data/lib/aigency/workspace/rm.rb +11 -0
- data/lib/aigency/workspace/tail.rb +11 -0
- data/lib/aigency/workspace/wc.rb +13 -0
- data/lib/aigency/workspace/write.rb +36 -0
- data/lib/aigency/workspace.rb +20 -7
- data/lib/aigency.rb +16 -13
- data/scaffold/{Rakefile → aigent/aigent.rake} +2 -11
- data/scaffold/enlist/.env.example +4 -0
- data/scaffold/{.gitignore → enlist/.gitignore} +1 -0
- data/scaffold/{Gemfile → enlist/Gemfile} +1 -1
- data/scaffold/enlist/README.md +90 -0
- data/scaffold/enlist/Rakefile +9 -0
- data/scaffold/enlist/bin/aigent +11 -0
- data/scaffold/{config → enlist/config}/schedule.rb +5 -0
- data/scaffold/sandbox/Dockerfile +37 -0
- data/scaffold/sandbox/docker-compose.yml +37 -0
- data/scaffold/sandbox/squid.conf +25 -0
- data/scaffold/sandbox/ssh_config +2 -0
- metadata +114 -16
- data/lib/aigency/tools.rb +0 -55
- data/lib/aigency/workspace/directory_deleter.rb +0 -23
- data/lib/aigency/workspace/directory_reader.rb +0 -33
- data/lib/aigency/workspace/file_deleter.rb +0 -22
- data/lib/aigency/workspace/file_reader.rb +0 -27
- data/lib/aigency/workspace/file_writer.rb +0 -26
- data/scaffold/README.md +0 -74
- data/scaffold/config/aigent.yml +0 -6
- /data/scaffold/{IDENTITY.md → enlist/IDENTITY.md} +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Your Aigent
|
|
2
|
+
|
|
3
|
+
An aigent (AI agent) is an intelligent assistant powered by language models through OpenAI-compatible APIs. It can read and write files in its private workspace and perform scheduled tasks on your behalf.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
### 1. Install dependencies
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bundle install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 2. Configure OpenAI API Connection
|
|
14
|
+
|
|
15
|
+
Copy the example env file:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cp .env.example .env
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Modify the `OPENAI_API_BASE` and `OPENAI_API_KEY` as needed. If you're using a local AI server or any other provider that is compatible with OpenAI, you can set the OPENAI_API_BASE config option to point there instead (e.g., `http://localhost:8080/v1`).
|
|
22
|
+
|
|
23
|
+
### 3. Define the Aigent's Personality
|
|
24
|
+
|
|
25
|
+
Edit `IDENTITY.md` to define how your aigent should behave:
|
|
26
|
+
|
|
27
|
+
```markdown
|
|
28
|
+
You are a professional assistant named Alex. You respond in a friendly but concise manner.
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This file sets the foundation for all the aigent's responses.
|
|
32
|
+
|
|
33
|
+
### 4. Configure Plugins
|
|
34
|
+
|
|
35
|
+
Aigency ships with two plugins: `workspace` and `sandbox`. The `workspace` plugin is enabled by default. It's recommended that you use one or the other, but not both.
|
|
36
|
+
|
|
37
|
+
The `workspace` plugin gives your aigent a directory where it can manage its own files.
|
|
38
|
+
|
|
39
|
+
The `sandbox` plugin provides a container where the aigent can not only manage files, but also run commands and scripts.
|
|
40
|
+
|
|
41
|
+
The `workspace` plugin is sufficient for many aigents. Switch to `sandbox` if you need your aigent to perform software development or other complex tasks.
|
|
42
|
+
|
|
43
|
+
### 5. Run setup
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
rake setup
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### Interactive Mode
|
|
52
|
+
|
|
53
|
+
Talk to your aigent using the `say` command:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
bin/aigent say "How many fibers are intertwined in a shredded wheat biscuit?"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Scheduling Tasks
|
|
60
|
+
|
|
61
|
+
Aigents use the `whenever` gem for scheduling. Example of a scheduled task:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
# config/schedule.rb
|
|
65
|
+
|
|
66
|
+
# Every day at 9am, the aigent will run the prompt in the DAILY_TASKS.md file
|
|
67
|
+
every 1.day, at: '9am' do
|
|
68
|
+
rake 'load[DAILY_TASKS.md]'
|
|
69
|
+
end
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Add the scheduled tasks to your crontab:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
bundle exec whenever --update-crontab
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
(Note: the `whenever` gem does not work on Windows.)
|
|
79
|
+
|
|
80
|
+
### Using the Sandbox
|
|
81
|
+
|
|
82
|
+
If you enable the `sandbox` plugin, you'll need to start the container:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
docker compose up -d
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The sandbox app is initialized with an egress that only allows network access to domains that are whitelisted in `squid.conf`. See the `http_targets` and `ssh_targets` ACLs.
|
|
89
|
+
|
|
90
|
+
Manage the sandbox user's SSH configuration in `data/sandbox_ssh`.
|
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
# Learn more: http://github.com/javan/whenever
|
|
21
21
|
|
|
22
|
+
job_type :rake, "cd :path && :environment_variable=:environment :bundle_command rake :task :output"
|
|
23
|
+
|
|
24
|
+
set :output, File.join(Dir.pwd, 'data', 'log', 'cron.log')
|
|
25
|
+
|
|
26
|
+
# Example job: run a prompt from a file named `DAILY.md` once a day
|
|
22
27
|
# every 1.day do
|
|
23
28
|
# rake "load[DAILY.md]"
|
|
24
29
|
# end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
FROM alpine:latest
|
|
2
|
+
|
|
3
|
+
RUN apk update && apk upgrade && apk add --no-cache \
|
|
4
|
+
autoconf \
|
|
5
|
+
bash \
|
|
6
|
+
bison \
|
|
7
|
+
build-base \
|
|
8
|
+
curl \
|
|
9
|
+
git \
|
|
10
|
+
libffi-dev \
|
|
11
|
+
linux-headers \
|
|
12
|
+
mise \
|
|
13
|
+
musl-dev \
|
|
14
|
+
netcat-openbsd \
|
|
15
|
+
nodejs \
|
|
16
|
+
openssh \
|
|
17
|
+
openssl \
|
|
18
|
+
openssl-dev \
|
|
19
|
+
perl \
|
|
20
|
+
pkgconf \
|
|
21
|
+
python3 \
|
|
22
|
+
tzdata \
|
|
23
|
+
xz \
|
|
24
|
+
yaml-dev \
|
|
25
|
+
zlib-dev
|
|
26
|
+
|
|
27
|
+
RUN adduser -D -h /sandbox user \
|
|
28
|
+
&& mkdir -p /opt/mise \
|
|
29
|
+
&& chown -R user:user /opt/mise
|
|
30
|
+
USER user
|
|
31
|
+
ENV MISE_DATA_DIR=/opt/mise \
|
|
32
|
+
MISE_CONFIG_DIR=/opt/mise/config \
|
|
33
|
+
MISE_TRUSTED_CONFIG_PATHS=/sandbox \
|
|
34
|
+
PATH=/opt/mise/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
35
|
+
RUN mise use -g ruby@3.4 && mise install --yes
|
|
36
|
+
|
|
37
|
+
CMD ["sleep", "infinity"]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
services:
|
|
2
|
+
app:
|
|
3
|
+
build:
|
|
4
|
+
context: .
|
|
5
|
+
dockerfile: ./sandbox/Dockerfile
|
|
6
|
+
networks: [sandbox]
|
|
7
|
+
restart: unless-stopped
|
|
8
|
+
depends_on:
|
|
9
|
+
- egress
|
|
10
|
+
volumes:
|
|
11
|
+
- ./data/sandbox:/sandbox
|
|
12
|
+
- ./data/sandbox_ssh:/sandbox/.ssh
|
|
13
|
+
working_dir: /sandbox
|
|
14
|
+
environment:
|
|
15
|
+
- http_proxy=http://egress:3128
|
|
16
|
+
- https_proxy=http://egress:3128
|
|
17
|
+
- HTTP_PROXY=http://egress:3128
|
|
18
|
+
- HTTPS_PROXY=http://egress:3128
|
|
19
|
+
- no_proxy=localhost,127.0.0.1,::1
|
|
20
|
+
- NO_PROXY=localhost,127.0.0.1,::1
|
|
21
|
+
command: ["sleep", "infinity"]
|
|
22
|
+
|
|
23
|
+
egress:
|
|
24
|
+
image: ubuntu/squid
|
|
25
|
+
networks: [sandbox, outside]
|
|
26
|
+
volumes:
|
|
27
|
+
- ./sandbox/squid.conf:/etc/squid/squid.conf:ro
|
|
28
|
+
|
|
29
|
+
networks:
|
|
30
|
+
sandbox:
|
|
31
|
+
internal: true
|
|
32
|
+
driver: bridge
|
|
33
|
+
driver_opts:
|
|
34
|
+
com.docker.network.bridge.gateway_mode_ipv4: isolated
|
|
35
|
+
com.docker.network.bridge.gateway_mode_ipv6: isolated
|
|
36
|
+
outside:
|
|
37
|
+
driver: bridge
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Allowlist-only forward proxy.
|
|
2
|
+
# NOTE: this file deliberately does NOT `include /etc/squid/conf.d/*`, so the
|
|
3
|
+
# rules Ubuntu ships in the image can't silently widen the allowlist.
|
|
4
|
+
|
|
5
|
+
http_port 3128
|
|
6
|
+
visible_hostname egress
|
|
7
|
+
cache deny all # forward proxy only, nothing to disk
|
|
8
|
+
access_log daemon:/var/log/squid/access.log
|
|
9
|
+
logfile_rotate 0
|
|
10
|
+
forwarded_for off # don't leak the container's IP downstream
|
|
11
|
+
|
|
12
|
+
acl SSL_ports port 443
|
|
13
|
+
acl Safe_ports port 80 443
|
|
14
|
+
acl http_targets dstdomain \
|
|
15
|
+
www.example.com
|
|
16
|
+
|
|
17
|
+
acl SSH_ports port 22
|
|
18
|
+
acl ssh_targets dstdomain \
|
|
19
|
+
ssh.example.com
|
|
20
|
+
|
|
21
|
+
http_access allow CONNECT ssh_targets SSH_ports
|
|
22
|
+
http_access deny !Safe_ports
|
|
23
|
+
http_access deny CONNECT !SSL_ports
|
|
24
|
+
http_access allow http_targets
|
|
25
|
+
http_access deny all
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: aigency
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Fred Snyder
|
|
@@ -9,6 +9,34 @@ bindir: exe
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: dotenv
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.2'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '3.2'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: faraday
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.15'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.15'
|
|
12
40
|
- !ruby/object:Gem::Dependency
|
|
13
41
|
name: fileutils
|
|
14
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -29,14 +57,14 @@ dependencies:
|
|
|
29
57
|
requirements:
|
|
30
58
|
- - "~>"
|
|
31
59
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '1
|
|
60
|
+
version: '2.1'
|
|
33
61
|
type: :runtime
|
|
34
62
|
prerelease: false
|
|
35
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
64
|
requirements:
|
|
37
65
|
- - "~>"
|
|
38
66
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '1
|
|
67
|
+
version: '2.1'
|
|
40
68
|
- !ruby/object:Gem::Dependency
|
|
41
69
|
name: thor
|
|
42
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -51,6 +79,48 @@ dependencies:
|
|
|
51
79
|
- - "~>"
|
|
52
80
|
- !ruby/object:Gem::Version
|
|
53
81
|
version: '1.5'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '13.0'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '13.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rspec
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '3.0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: simplecov
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '0.21'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '0.21'
|
|
54
124
|
email:
|
|
55
125
|
- fsnyder@castwide.com
|
|
56
126
|
executables:
|
|
@@ -64,25 +134,53 @@ files:
|
|
|
64
134
|
- exe/aigency
|
|
65
135
|
- lib/aigency.rb
|
|
66
136
|
- lib/aigency/aigent.rb
|
|
137
|
+
- lib/aigency/aigent/current_time.rb
|
|
138
|
+
- lib/aigency/aigent/shell.rb
|
|
139
|
+
- lib/aigency/delegator.rb
|
|
140
|
+
- lib/aigency/plugin.rb
|
|
141
|
+
- lib/aigency/plugin/shell.rb
|
|
142
|
+
- lib/aigency/rake.rb
|
|
143
|
+
- lib/aigency/sandbox.rb
|
|
144
|
+
- lib/aigency/sandbox/exec.rb
|
|
67
145
|
- lib/aigency/shell.rb
|
|
146
|
+
- lib/aigency/tempdir.rb
|
|
147
|
+
- lib/aigency/tempdir/helpers.rb
|
|
148
|
+
- lib/aigency/tempdir/list.rb
|
|
149
|
+
- lib/aigency/tempdir/read.rb
|
|
150
|
+
- lib/aigency/tempdir/size.rb
|
|
151
|
+
- lib/aigency/tempdir/write.rb
|
|
68
152
|
- lib/aigency/tool.rb
|
|
69
|
-
- lib/aigency/tools.rb
|
|
70
153
|
- lib/aigency/usability.rb
|
|
71
154
|
- lib/aigency/version.rb
|
|
72
155
|
- lib/aigency/workspace.rb
|
|
73
|
-
- lib/aigency/workspace/
|
|
74
|
-
- lib/aigency/workspace/
|
|
75
|
-
- lib/aigency/workspace/
|
|
76
|
-
- lib/aigency/workspace/
|
|
77
|
-
- lib/aigency/workspace/
|
|
156
|
+
- lib/aigency/workspace/cat.rb
|
|
157
|
+
- lib/aigency/workspace/cmd.rb
|
|
158
|
+
- lib/aigency/workspace/copy_tempdir_file.rb
|
|
159
|
+
- lib/aigency/workspace/cp.rb
|
|
160
|
+
- lib/aigency/workspace/diff.rb
|
|
161
|
+
- lib/aigency/workspace/grep.rb
|
|
162
|
+
- lib/aigency/workspace/head.rb
|
|
78
163
|
- lib/aigency/workspace/helpers.rb
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
164
|
+
- lib/aigency/workspace/ls.rb
|
|
165
|
+
- lib/aigency/workspace/mkdir.rb
|
|
166
|
+
- lib/aigency/workspace/mv.rb
|
|
167
|
+
- lib/aigency/workspace/rm.rb
|
|
168
|
+
- lib/aigency/workspace/tail.rb
|
|
169
|
+
- lib/aigency/workspace/wc.rb
|
|
170
|
+
- lib/aigency/workspace/write.rb
|
|
171
|
+
- scaffold/aigent/aigent.rake
|
|
172
|
+
- scaffold/enlist/.env.example
|
|
173
|
+
- scaffold/enlist/.gitignore
|
|
174
|
+
- scaffold/enlist/Gemfile
|
|
175
|
+
- scaffold/enlist/IDENTITY.md
|
|
176
|
+
- scaffold/enlist/README.md
|
|
177
|
+
- scaffold/enlist/Rakefile
|
|
178
|
+
- scaffold/enlist/bin/aigent
|
|
179
|
+
- scaffold/enlist/config/schedule.rb
|
|
180
|
+
- scaffold/sandbox/Dockerfile
|
|
181
|
+
- scaffold/sandbox/docker-compose.yml
|
|
182
|
+
- scaffold/sandbox/squid.conf
|
|
183
|
+
- scaffold/sandbox/ssh_config
|
|
86
184
|
- sig/aigency.rbs
|
|
87
185
|
licenses: []
|
|
88
186
|
metadata: {}
|
data/lib/aigency/tools.rb
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aigency
|
|
4
|
-
module Tools
|
|
5
|
-
# @return [Array<Class<Tool>>]
|
|
6
|
-
def self.registry
|
|
7
|
-
@registry ||= []
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
# @return [Hash{String => String}]
|
|
11
|
-
def self.config_map
|
|
12
|
-
@configs ||= {}
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
# @return [Array<String>]
|
|
16
|
-
def self.directories
|
|
17
|
-
@directories ||= []
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Register a tool.
|
|
21
|
-
#
|
|
22
|
-
# @param klass [Class<Tool>]
|
|
23
|
-
# @return [void]
|
|
24
|
-
def self.register klass
|
|
25
|
-
registry.push klass
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Define a default configuration.
|
|
29
|
-
#
|
|
30
|
-
# @param name [String] The name of the config section
|
|
31
|
-
# @param text [String] YAML-formatted config data
|
|
32
|
-
# @return [void]
|
|
33
|
-
def self.configure name, text
|
|
34
|
-
config_map[name] = text
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Define directories to be created relative to an aigent's root.
|
|
38
|
-
#
|
|
39
|
-
def self.mkdir_p *paths
|
|
40
|
-
directories.concat paths
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
Tools.configure 'aigent', <<~EOF
|
|
45
|
-
name: an Aigent
|
|
46
|
-
openai_api_base: https://api.openai.com/v1
|
|
47
|
-
openai_api_key: CHANGE_ME
|
|
48
|
-
require:
|
|
49
|
-
- aigency/email
|
|
50
|
-
- aigency/wikipedia
|
|
51
|
-
- aigency/workspace
|
|
52
|
-
EOF
|
|
53
|
-
|
|
54
|
-
Tools.mkdir_p 'data/chats', 'data/log'
|
|
55
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aigency
|
|
4
|
-
module Workspace
|
|
5
|
-
class DirectoryDeleter < Tool
|
|
6
|
-
include Helpers
|
|
7
|
-
|
|
8
|
-
desc "Delete a directory and all of its contents from your private workspace"
|
|
9
|
-
|
|
10
|
-
def execute(directory_name:)
|
|
11
|
-
aigent.log.puts "[Workspace::DirectoryDeleter] #{directory_name}"
|
|
12
|
-
|
|
13
|
-
resolved = expand_to_workspace(directory_name)
|
|
14
|
-
FileUtils.rm_rf(resolved)
|
|
15
|
-
{ dirname: directory_name, success: true }
|
|
16
|
-
rescue StandardError => e
|
|
17
|
-
{ success: false, error: "[#{e.class}] #{e.message}"}
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
Aigency::Tools.register Aigency::Workspace::DirectoryDeleter
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aigency
|
|
4
|
-
module Workspace
|
|
5
|
-
class DirectoryReader < Tool
|
|
6
|
-
include Helpers
|
|
7
|
-
|
|
8
|
-
desc "Get the contents of a directory from your private workspace"
|
|
9
|
-
|
|
10
|
-
def execute(directory_name:)
|
|
11
|
-
aigent.log.puts "[Workspace::DirectoryReader] Reading #{directory_name}"
|
|
12
|
-
resolved = expand_to_workspace(directory_name)
|
|
13
|
-
if File.directory?(resolved)
|
|
14
|
-
{
|
|
15
|
-
directory: directory_name,
|
|
16
|
-
success: true,
|
|
17
|
-
entries: Dir.entries(resolved)[2..]
|
|
18
|
-
}
|
|
19
|
-
else
|
|
20
|
-
{
|
|
21
|
-
directory: directory_name,
|
|
22
|
-
success: false,
|
|
23
|
-
error: "Not a directory"
|
|
24
|
-
}
|
|
25
|
-
end
|
|
26
|
-
rescue StandardError => e
|
|
27
|
-
{ success: false, error: "[#{e.class}] #{e.message}" }
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
Aigency::Tools.register Aigency::Workspace::DirectoryReader
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aigency
|
|
4
|
-
module Workspace
|
|
5
|
-
class FileDeleter < Tool
|
|
6
|
-
include Helpers
|
|
7
|
-
|
|
8
|
-
desc "Delete a file from your private workspace"
|
|
9
|
-
|
|
10
|
-
def execute(filename:)
|
|
11
|
-
aigent.log.puts "[Workspace::FileDeleter] Deleting file #{filename}"
|
|
12
|
-
resolved = expand_to_workspace(filename)
|
|
13
|
-
File.delete resolved
|
|
14
|
-
{ filename: filename, success: true }
|
|
15
|
-
rescue StandardError => e
|
|
16
|
-
{ success: false, error: "[#{e.class}] #{e.message}" }
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
Aigency::Tools.register Aigency::Workspace::FileDeleter
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Aigency
|
|
4
|
-
module Workspace
|
|
5
|
-
class FileReader < Tool
|
|
6
|
-
include Helpers
|
|
7
|
-
|
|
8
|
-
desc "Read a file from your private workspace"
|
|
9
|
-
|
|
10
|
-
def execute(filename:)
|
|
11
|
-
aigent.log.puts "[Workspace::FileReader] Reading #{filename}"
|
|
12
|
-
|
|
13
|
-
resolved = expand_to_workspace(filename)
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
success: true,
|
|
17
|
-
filename: filename,
|
|
18
|
-
content: File.read(resolved)
|
|
19
|
-
}
|
|
20
|
-
rescue StandardError => e
|
|
21
|
-
{ success: false, error: "[#{e.class}] #{e.message}"}
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
Aigency::Tools.register Aigency::Workspace::FileReader
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'fileutils'
|
|
4
|
-
|
|
5
|
-
module Aigency
|
|
6
|
-
module Workspace
|
|
7
|
-
class FileWriter < Tool
|
|
8
|
-
include Helpers
|
|
9
|
-
|
|
10
|
-
desc "Write a file to your private workspace"
|
|
11
|
-
|
|
12
|
-
def execute(filename:, content:)
|
|
13
|
-
aigent.log.puts "[Workspace::FileWriter] Writing #{filename}"
|
|
14
|
-
|
|
15
|
-
resolved = expand_to_workspace(filename)
|
|
16
|
-
FileUtils.mkdir_p File.dirname(resolved)
|
|
17
|
-
File.write resolved, content
|
|
18
|
-
return { filename: filename, success: true }
|
|
19
|
-
rescue StandardError => e
|
|
20
|
-
{ success: false, error: "[#{e.class}] #{e.message}" }
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
Aigency::Tools.register Aigency::Workspace::FileWriter
|
data/scaffold/README.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Your Aigent
|
|
2
|
-
|
|
3
|
-
An aigent (AI agent) is an intelligent assistant powered by language models through OpenAI-compatible APIs. It can read and write files in its private workspace and perform scheduled tasks on your behalf.
|
|
4
|
-
|
|
5
|
-
## Configuration
|
|
6
|
-
|
|
7
|
-
### Install dependencies
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
bundle install
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
### Initial setup
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
rake setup
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### 1. Configure the Aigent
|
|
20
|
-
|
|
21
|
-
Configure the aigent's settings in `config/aigent.yml`.
|
|
22
|
-
|
|
23
|
-
#### OpenAI-Compatible Providers
|
|
24
|
-
|
|
25
|
-
If you're using a local AI server or any other provider that is compatible with OpenAI, you can set the OPENAI_API_BASE config option to point there instead (e.g., `http://localhost:8080/v1`).
|
|
26
|
-
|
|
27
|
-
### 2. Define the Aigent's Personality
|
|
28
|
-
|
|
29
|
-
Edit `IDENTITY.md` to define how your aigent should behave:
|
|
30
|
-
|
|
31
|
-
```markdown
|
|
32
|
-
You are a professional assistant named Alex. You respond in a friendly but concise manner.
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
This file sets the foundation for all the aigent's responses.
|
|
36
|
-
|
|
37
|
-
## Usage
|
|
38
|
-
|
|
39
|
-
### Interactive Mode
|
|
40
|
-
|
|
41
|
-
Talk to your aigent using the Rake task:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
rake say["Tell me about project progress"]
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### The Workspace
|
|
48
|
-
|
|
49
|
-
Your aigent has read/write access to everything in the `data/workspace` directory.
|
|
50
|
-
|
|
51
|
-
### Scheduling Tasks
|
|
52
|
-
|
|
53
|
-
The project includes the `whenever` gem for scheduling. Example of a scheduled task:
|
|
54
|
-
|
|
55
|
-
```ruby
|
|
56
|
-
# config/schedule.rb
|
|
57
|
-
|
|
58
|
-
# Every day at 9am, the aigent will run the prompt in the DAILY_TASKS.md file
|
|
59
|
-
every 1.day, at: '9am' do
|
|
60
|
-
rake 'load[DAILY_TASKS.md]'
|
|
61
|
-
end
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Add the scheduled tasks to your crontab:
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
bundle exec whenever --update-crontab
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
(Note: the `whenever` gem does not work on Windows.)
|
|
71
|
-
|
|
72
|
-
## Aigent Tools
|
|
73
|
-
|
|
74
|
-
You can give your aigent more functionality by installing additional tools. It ships with the `Workspace` tool, which gives it full read/write access to the `data/workspace` directory.
|
data/scaffold/config/aigent.yml
DELETED
|
File without changes
|