ask-agent 0.23.0 → 0.24.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 +18 -0
- data/README.md +36 -0
- data/lib/ask/agent/definition.rb +6 -4
- data/lib/ask/agent/version.rb +1 -1
- data/lib/ask/agent.rb +23 -4
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bd63de3a8095e799ea8d20b85973d6d1235b7d5799b7a5114982e6ac5a318537
|
|
4
|
+
data.tar.gz: 5c61e5fe8075a348ef40b643c1da1a313530ce53d5b7e3160fc4a6d832d8bb94
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d203c97f1a1b232cb40a3103f485c23c1d3e09bc1e5d0112a2bf31add57d24cfd36cfc452bc366d051baf4c3f445a53567477a089f4770dfa77f872d0f621c5e
|
|
7
|
+
data.tar.gz: b390769fa7c9ccedc0d30a8d4acab448222f8d9ac0e8e4608a40d2cf85cb7ca5eac8c0bc4daa2e1e79c461f339c358e27f395b2e04033a6e4b9fd2de4ec4f089
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
## [0.24.0] — 2026-07-30
|
|
2
|
+
|
|
3
|
+
### Changed
|
|
4
|
+
|
|
5
|
+
- **Agent class convention is now `<Name>::Agent`, not `<Name>Agent`.**
|
|
6
|
+
`agents/health_check/agent.rb` defines `module HealthCheck; class Agent <
|
|
7
|
+
Ask::Agent::Definition` — matching the ecosystem's `Xxx::Workflow` /
|
|
8
|
+
`Xxx::Create` naming. Directory-based discovery is unchanged.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Discovery re-points definitions when the class constant is re-opened.**
|
|
13
|
+
Requiring an `agent.rb` from a second location (same agent name, e.g. test
|
|
14
|
+
fixtures) re-opens the existing `<Name>::Agent` constant instead of
|
|
15
|
+
redefining it, so `inherited` never fires and the definition kept its old
|
|
16
|
+
directory. Discovery now falls back to matching by conventional class name
|
|
17
|
+
and re-points `_config[:dir]` at the current directory.
|
|
18
|
+
|
|
1
19
|
## [0.23.0] — 2026-07-30
|
|
2
20
|
|
|
3
21
|
### Added
|
data/README.md
CHANGED
|
@@ -213,6 +213,42 @@ c.middleware.use :model_fallback,
|
|
|
213
213
|
eligible_errors: [Ask::RateLimitError, Ask::ServerError]
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
+
## Agents
|
|
217
|
+
|
|
218
|
+
Declarative agents follow a file convention. Each agent lives in a
|
|
219
|
+
directory under `agents/` (or `app/agents/` in Rails); the directory
|
|
220
|
+
name is the agent name, the file `agent.rb` defines the agent as a
|
|
221
|
+
`<Name>::Agent < Ask::Agent::Definition` subclass, and a sibling
|
|
222
|
+
`instructions.md` is auto-loaded as the system prompt.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
agents/
|
|
226
|
+
└── health_check/ # agent name: "health_check"
|
|
227
|
+
├── agent.rb # module HealthCheck; class Agent < Ask::Agent::Definition
|
|
228
|
+
├── instructions.md # auto-loaded system prompt
|
|
229
|
+
└── tools/ # per-agent tools (referenced with `tools :name`)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```ruby
|
|
233
|
+
# agents/health_check/agent.rb
|
|
234
|
+
module HealthCheck
|
|
235
|
+
class Agent < Ask::Agent::Definition
|
|
236
|
+
model "gpt-4o"
|
|
237
|
+
tools :bash, :read, :grep
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Run it by name:
|
|
243
|
+
|
|
244
|
+
```ruby
|
|
245
|
+
agent = Ask::Agent.new("health_check")
|
|
246
|
+
response = agent.run("Check server health")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Shared tools for all agents go in `agents/shared/tools/`. Per-agent
|
|
250
|
+
skills go in `agents/<name>/skills/`, shared skills in `agents/shared/skills/`.
|
|
251
|
+
|
|
216
252
|
## Configuration
|
|
217
253
|
|
|
218
254
|
```ruby
|
data/lib/ask/agent/definition.rb
CHANGED
|
@@ -9,10 +9,12 @@ module Ask
|
|
|
9
9
|
# Instructions load automatically from a sibling +instructions.md+.
|
|
10
10
|
#
|
|
11
11
|
# @example +agents/health_check/agent.rb+
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
12
|
+
# module HealthCheck
|
|
13
|
+
# class Agent < Ask::Agent::Definition
|
|
14
|
+
# model "gpt-4o"
|
|
15
|
+
# tools :bash, :read, :grep
|
|
16
|
+
# schedule "every 5 minutes"
|
|
17
|
+
# end
|
|
16
18
|
# end
|
|
17
19
|
#
|
|
18
20
|
# # agents/health_check/instructions.md is auto-loaded
|
data/lib/ask/agent/version.rb
CHANGED
data/lib/ask/agent.rb
CHANGED
|
@@ -117,10 +117,13 @@ module Ask
|
|
|
117
117
|
|
|
118
118
|
require file
|
|
119
119
|
|
|
120
|
-
# Find the Definition subclass whose directory matches
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
120
|
+
# Find the Definition subclass whose directory matches.
|
|
121
|
+
# Falls back to matching by conventional class name
|
|
122
|
+
# (<Name>::Agent) for agents re-opened from another location
|
|
123
|
+
# (e.g. same-named fixtures across test runs) — Ruby reopens
|
|
124
|
+
# an existing constant instead of redefining it, so the
|
|
125
|
+
# inherited hook doesn't fire a second time.
|
|
126
|
+
match = find_definition_for(dir, name)
|
|
124
127
|
|
|
125
128
|
if match
|
|
126
129
|
@registry[name] = [match, dir]
|
|
@@ -129,6 +132,22 @@ module Ask
|
|
|
129
132
|
end
|
|
130
133
|
end
|
|
131
134
|
|
|
135
|
+
# Find the Definition subclass for an agent directory.
|
|
136
|
+
#
|
|
137
|
+
# First tries an exact directory match (fresh definitions). When the
|
|
138
|
+
# class constant already exists — loaded from a different directory
|
|
139
|
+
# with the same agent name — re-points it at this directory so the
|
|
140
|
+
# returned definition is always current.
|
|
141
|
+
def find_definition_for(dir, name)
|
|
142
|
+
match = Definition.subclasses.find { |klass| klass._config[:dir] == dir }
|
|
143
|
+
return match if match
|
|
144
|
+
|
|
145
|
+
convention_name = name.split("_").map(&:capitalize).join + "::Agent"
|
|
146
|
+
match = Definition.subclasses.find { |klass| klass.name == convention_name }
|
|
147
|
+
match&._config&.[]=(:dir, dir)
|
|
148
|
+
match
|
|
149
|
+
end
|
|
150
|
+
|
|
132
151
|
def discover_shared_tools(base)
|
|
133
152
|
shared_tools_dir = File.join(base, "shared", "tools")
|
|
134
153
|
return unless File.directory?(shared_tools_dir)
|