little_ghost 0.1.0 → 0.2.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/README.md +50 -47
- data/docs/guides/{Core Concepts.md → core_concepts.md} +40 -20
- data/docs/guides/getting_started.md +164 -0
- data/lib/little_ghost/ag_ui/adapter.rb +1 -1
- data/lib/little_ghost/agent/context_management.rb +1 -4
- data/lib/little_ghost/agent.rb +94 -26
- data/lib/little_ghost/agent_builder.rb +1 -1
- data/lib/little_ghost/configuration.rb +210 -29
- data/lib/little_ghost/data/model_catalog.json +19178 -0
- data/lib/little_ghost/errors.rb +6 -0
- data/lib/little_ghost/invocation.rb +2 -17
- data/lib/little_ghost/model.rb +53 -33
- data/lib/little_ghost/model_capabilities.rb +6 -5
- data/lib/little_ghost/model_resolver.rb +316 -0
- data/lib/little_ghost/models/catalog/models_dev_source.rb +62 -0
- data/lib/little_ghost/models/catalog/source.rb +30 -0
- data/lib/little_ghost/models/catalog.rb +154 -0
- data/lib/little_ghost/models/catalog_snapshot.rb +44 -0
- data/lib/little_ghost/models/configuration.rb +43 -0
- data/lib/little_ghost/models/details.rb +48 -0
- data/lib/little_ghost/models/target.rb +29 -0
- data/lib/little_ghost/provider_registry.rb +75 -0
- data/lib/little_ghost/providers/anthropic/catalog_source.rb +31 -0
- data/lib/little_ghost/providers/anthropic.rb +222 -0
- data/lib/little_ghost/providers/base.rb +46 -0
- data/lib/little_ghost/providers/bedrock/aws_protocol.rb +132 -0
- data/lib/little_ghost/providers/bedrock/catalog_source.rb +200 -0
- data/lib/little_ghost/providers/bedrock/credential_resolver.rb +123 -0
- data/lib/little_ghost/providers/bedrock/http_client.rb +78 -0
- data/lib/little_ghost/providers/bedrock.rb +23 -15
- data/lib/little_ghost/providers/configuration.rb +79 -0
- data/lib/little_ghost/providers/gemini/catalog_source.rb +35 -0
- data/lib/little_ghost/providers/gemini.rb +204 -0
- data/lib/little_ghost/providers/open_router/catalog_source.rb +42 -0
- data/lib/little_ghost/providers/open_router.rb +6 -2
- data/lib/little_ghost/providers/openai_compatible.rb +19 -23
- data/lib/little_ghost/providers/vertex_ai/credential_resolver.rb +90 -0
- data/lib/little_ghost/providers/vertex_ai.rb +38 -0
- data/lib/little_ghost/run.rb +7 -7
- data/lib/little_ghost/runtime.rb +10 -7
- data/lib/little_ghost/sandbox.rb +5 -5
- data/lib/little_ghost/session_store.rb +3 -3
- data/lib/little_ghost/structured_output.rb +2 -8
- data/lib/little_ghost/support/http_client.rb +186 -0
- data/lib/little_ghost/{providers → support}/sse_parser.rb +1 -1
- data/lib/little_ghost/tool.rb +5 -1
- data/lib/little_ghost/tool_registry.rb +2 -3
- data/lib/little_ghost/version.rb +1 -1
- data/lib/little_ghost/workflow.rb +1 -1
- data/lib/little_ghost.rb +21 -15
- metadata +28 -7
- data/docs/guides/Getting Started.md +0 -187
- data/lib/little_ghost/default_model_registry.rb +0 -71
- data/lib/little_ghost/model_registry.rb +0 -173
- data/lib/little_ghost/providers/http_transport.rb +0 -149
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cfcd337b2268f123e2e64e4bdb63a68e3f093395888dac5b0e4fe18ce0f800c6
|
|
4
|
+
data.tar.gz: 31dc093cea43764a4f8526c140bb57d56752da34c2cbced63d96f2a68eeab41b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b1ad15e0aa91583641dcd752a0b4157151b216672c0431c77d6b76293ee73e2841e9e39b49988c9517533f10f22014e376bb5c86d41929c62f6d2de83df3a81e
|
|
7
|
+
data.tar.gz: d39231bad7f80f01db55a6c8ba6af68292205f81f06f887149cb03bc68f777d4e759bc1c64bae661ebe25ba8b3118240c19a6876a2cf0e24712652776de52426
|
data/README.md
CHANGED
|
@@ -6,26 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
<hr>
|
|
8
8
|
|
|
9
|
-
Bring agents and agentic workflows into an existing Ruby system, or use them as the core of a dedicated AI service. LittleGhost
|
|
9
|
+
Bring agents and agentic workflows into an existing Ruby system, or use them as the core of a dedicated AI service. LittleGhost connects model providers, tools, streaming, sessions, delegation, deterministic workflows, and observability through Ruby APIs.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Set `OPENAI_API_KEY`, then paste this customer support agent into a Ruby console or file. It selects a model directly and exposes one validated application tool:
|
|
12
12
|
|
|
13
13
|
```ruby
|
|
14
14
|
require "little_ghost"
|
|
15
15
|
|
|
16
|
-
class CustomerSupportModels < LittleGhost::ModelRegistry
|
|
17
|
-
def initialize
|
|
18
|
-
super
|
|
19
|
-
provider(:openai) do |model:, **|
|
|
20
|
-
LittleGhost::Providers::OpenAI.new(
|
|
21
|
-
api_key: ENV.fetch("OPENAI_API_KEY"),
|
|
22
|
-
model:
|
|
23
|
-
)
|
|
24
|
-
end
|
|
25
|
-
profile "customer_support", provider: :openai, model: "gpt-5"
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
16
|
class HelpCenterLookupTool < LittleGhost::Tool
|
|
30
17
|
description "Look up a help center entry by topic."
|
|
31
18
|
input_schema(
|
|
@@ -43,80 +30,96 @@ end
|
|
|
43
30
|
|
|
44
31
|
class CustomerSupportAgent < LittleGhost::Agent
|
|
45
32
|
description "Answers customer support questions."
|
|
46
|
-
model "
|
|
33
|
+
model "openai:gpt-5.6-luna"
|
|
47
34
|
system_prompt "Answer clearly. Check the help center before stating company guidance."
|
|
48
35
|
tools HelpCenterLookupTool
|
|
49
36
|
end
|
|
50
37
|
|
|
51
|
-
LittleGhost.configure { |config| config.models CustomerSupportModels }
|
|
52
|
-
|
|
53
38
|
run = CustomerSupportAgent.ask("Can I get a refund after two weeks?")
|
|
54
39
|
puts run.response
|
|
55
40
|
# One possible response:
|
|
56
41
|
# Refunds are available within 30 days, so your purchase is eligible.
|
|
57
42
|
```
|
|
58
43
|
|
|
59
|
-
The
|
|
60
|
-
|
|
61
|
-
LittleGhost keeps the model loop provider-neutral. Tools can run in parallel, mutating tools can opt into a run-wide exclusive lock, and oversized tool results are truncated to the configured limit before they enter model context. Strict result schemas, cancellation, deadlines, session checkpoints, structured events, and OpenTelemetry integration are available when an application needs them; none are required to define the first agent.
|
|
44
|
+
The completed `LittleGhost::Run` exposes its outcome, final response, normalized messages, token usage, and terminal error. Streaming callers receive `LittleGhost::StreamEvent` objects instead of provider-specific payloads:
|
|
62
45
|
|
|
63
|
-
|
|
46
|
+
```ruby
|
|
47
|
+
CustomerSupportAgent.stream_ask("Can I get a refund?").each do |event|
|
|
48
|
+
print event.data.fetch(:text) if event.type == :text_delta
|
|
49
|
+
end
|
|
50
|
+
```
|
|
64
51
|
|
|
65
|
-
## How
|
|
52
|
+
## How the pieces fit
|
|
66
53
|
|
|
67
54
|
```text
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
provider connections + model selections ──> ModelResolver ──> provider
|
|
56
|
+
│
|
|
70
57
|
request ──> CustomerSupportAgent ──> HelpCenterLookupTool
|
|
71
58
|
│
|
|
72
|
-
└────────> ResearchAgent
|
|
59
|
+
└────────> ResearchAgent subagent
|
|
73
60
|
|
|
74
61
|
request ──> ResponseWorkflow ──> ResearchAgent ──> CustomerSupportAgent
|
|
75
62
|
```
|
|
76
63
|
|
|
77
|
-
Configuration owns shared services such as model
|
|
64
|
+
Configuration owns shared services such as model resolution, sessions, lookup paths, workspaces, sandboxes, and instrumentation. Agent classes own behavior: their model selection, prompt, tools, limits, result schema, and delegation policy. Tools expose narrow application operations. A subagent lets the model delegate within configured limits; a workflow uses ordinary Ruby when the application must control ordering.
|
|
78
65
|
|
|
79
|
-
|
|
66
|
+
Each top-level execution owns a run lifecycle. The run checkpoints session state, closes its resources, aggregates usage, and emits framework events whether the entrypoint is an agent or a workflow.
|
|
80
67
|
|
|
81
|
-
|
|
68
|
+
## Installation and configuration
|
|
69
|
+
|
|
70
|
+
LittleGhost requires Ruby 3.3 or newer. Add it to your bundle:
|
|
82
71
|
|
|
83
72
|
```ruby
|
|
84
|
-
|
|
85
|
-
print event.data[:text] if event.type == :text_delta
|
|
86
|
-
end
|
|
73
|
+
gem "little_ghost"
|
|
87
74
|
```
|
|
88
75
|
|
|
89
|
-
|
|
76
|
+
Then run `bundle install`. Built-in OpenAI-compatible, OpenRouter, Anthropic, Gemini, Vertex AI, and Amazon Bedrock integrations use Ruby's standard library and normalize responses into the same protocol.
|
|
90
77
|
|
|
91
|
-
|
|
78
|
+
Configuration does not require a particular directory layout. Provider connections and model profiles resolve independently in this order:
|
|
92
79
|
|
|
93
|
-
|
|
80
|
+
1. An inline `config.providers` or `config.models` declaration.
|
|
81
|
+
2. The corresponding explicit `config.providers_path` or `config.models_path`.
|
|
82
|
+
3. The optional conventional file under `config/little_ghost/`.
|
|
83
|
+
4. Environment-based provider selection and the built-in `default` profile.
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
An explicit path must exist. A missing conventional file is valid. The conventional form keeps connection policy separate from model roles:
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
# config/little_ghost/providers.yml
|
|
89
|
+
providers:
|
|
90
|
+
openai:
|
|
91
|
+
adapter: openai
|
|
92
|
+
api_key: <%= ENV.fetch("OPENAI_API_KEY") %>
|
|
97
93
|
```
|
|
98
94
|
|
|
99
|
-
|
|
95
|
+
```yaml
|
|
96
|
+
# config/little_ghost/models.yml
|
|
97
|
+
default_model: customer_support
|
|
98
|
+
models:
|
|
99
|
+
customer_support:
|
|
100
|
+
target: openai:gpt-5.6-luna
|
|
101
|
+
```
|
|
100
102
|
|
|
101
|
-
By default, LittleGhost maps
|
|
103
|
+
By default, LittleGhost maps `default` to GPT-5.6 Luna. It configures conventional OpenRouter and OpenAI connections from nonblank `LITTLEGHOST_OPENROUTER_API_KEY`, `LITTLEGHOST_OPENAI_API_KEY`, `OPENROUTER_API_KEY`, and `OPENAI_API_KEY` values; that order determines the default when more than one provider is available. Model inputs—including prompts, history, tool data, and attachments—leave the application for the selected external provider. Configure providers explicitly when provider choice or data residency matters.
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
Applications that need custom routing can subclass `LittleGhost::ModelResolver` and install the class with `config.model_resolver`. A custom resolver owns its profiles and default role; configuring `models`, `models_path`, or `default_model` at the same time is an error. Provider configuration remains available to the resolver.
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
LittleGhost runs inside the surrounding Ruby process; it does not prescribe an HTTP server, CLI, job system, or application layout. `config/little_ghost`, `app/agents`, `app/prompts`, `app/tools`, and `app/skills` are optional conventions. Every path can be configured, and agents, prompts, and tools may live wherever the application loads them.
|
|
106
108
|
|
|
107
109
|
## Documentation
|
|
108
110
|
|
|
109
|
-
- [
|
|
110
|
-
- [
|
|
111
|
-
- [
|
|
112
|
-
- [API reference](rdoc-ref:LittleGhost) covers exact signatures, options, and lifecycle details.
|
|
111
|
+
- [Getting Started](docs/guides/getting_started.md) builds and streams the customer support example.
|
|
112
|
+
- [Core Concepts](docs/guides/core_concepts.md) explains models, agents, tools, runs, delegation, workflows, and sessions.
|
|
113
|
+
- [API reference](rdoc-ref:LittleGhost) covers exact signatures, options, and lifecycle behavior.
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
## Contributing
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
See the [contributing guide](https://github.com/mattyr/little_ghost/blob/main/CONTRIBUTING.md), [Code of Conduct](https://github.com/mattyr/little_ghost/blob/main/CODE_OF_CONDUCT.md), and [security policy](https://github.com/mattyr/little_ghost/blob/main/SECURITY.md).
|
|
117
118
|
|
|
118
119
|
```sh
|
|
119
120
|
bundle install
|
|
120
121
|
bundle exec rake test
|
|
121
122
|
bundle exec standardrb --no-fix
|
|
122
123
|
```
|
|
124
|
+
|
|
125
|
+
LittleGhost is licensed under the MIT License.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Core Concepts
|
|
2
2
|
|
|
3
|
-
LittleGhost gives Ruby software two ways to compose AI behavior. Agents can choose among validated tools and delegated specialists, while agentic workflows keep required ordering and branching under application control. The customer support example makes that boundary visible:
|
|
3
|
+
LittleGhost gives Ruby software two ways to compose AI behavior. Agents can choose among validated tools and delegated specialists, while agentic workflows keep required ordering and branching under application control. The customer support example makes that boundary visible: ModelResolver chooses provider-backed models, CustomerSupportAgent owns behavior, HelpCenterLookupTool exposes a narrow help center lookup, ResearchAgent handles delegated investigation, and ResponseWorkflow imposes a deterministic sequence when the surrounding system requires one.
|
|
4
4
|
|
|
5
5
|
```text
|
|
6
6
|
shared configuration
|
|
7
|
-
└──
|
|
7
|
+
└── ModelResolver ── resolves model selections ──> provider clients
|
|
8
8
|
|
|
9
9
|
one request
|
|
10
10
|
└── Run
|
|
@@ -17,28 +17,48 @@ one deterministic request
|
|
|
17
17
|
└── Run ──> ResponseWorkflow ──> ResearchAgent ──> CustomerSupportAgent
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
## Models
|
|
20
|
+
## Models can be selected directly or by role
|
|
21
21
|
|
|
22
|
-
An agent
|
|
22
|
+
An agent can name a canonical target directly when the choice belongs beside its behavior:
|
|
23
23
|
|
|
24
24
|
```ruby
|
|
25
|
-
class
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
class CustomerSupportAgent < LittleGhost::Agent
|
|
26
|
+
model "openai:gpt-5.6-luna"
|
|
27
|
+
end
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
It can also attach trusted model settings without defining a shared profile:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
class DeliberateSupportAgent < LittleGhost::Agent
|
|
34
|
+
model(provider: "openai", model: "gpt-5.6-luna", reasoning_effort: "high")
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
In both forms, `provider` is the name of a configured connection. A role such as `customer_support` adds stable application vocabulary when several agents or deployments should share routing policy:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
LittleGhost.configure do |config|
|
|
42
|
+
config.providers = {
|
|
43
|
+
openai: {adapter: :openai, api_key: ENV.fetch("OPENAI_API_KEY")}
|
|
44
|
+
}
|
|
45
|
+
config.models = {
|
|
46
|
+
customer_support: {target: "openai:gpt-5.6-luna"}
|
|
47
|
+
}
|
|
36
48
|
end
|
|
37
49
|
```
|
|
38
50
|
|
|
39
|
-
|
|
51
|
+
```ruby
|
|
52
|
+
class CustomerSupportAgent < LittleGhost::Agent
|
|
53
|
+
model :customer_support
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Strings and symbols without a colon are roles; strings containing a colon are canonical targets; mappings require `provider` and `model`, with remaining keys treated as model settings. Role names cannot contain a colon. Direct targets and mappings bypass role inheritance and overlays.
|
|
58
|
+
|
|
59
|
+
Dotted roles inherit from the nearest registered parent. `ResearchAgent` can request `customer_support.research` and initially use the `customer_support` profile; registering `customer_support.research` later specializes it. A resolver caller may pass an explicit `profiles:` overlay without mutating the configured profiles or agent class. Because an overlay can select a different registered provider, model, and settings, it is trusted application configuration and must be constructed or allowlisted by the application rather than copied from unchecked request data. The base resolver does not inspect application-specific invocation fields.
|
|
40
60
|
|
|
41
|
-
The provider performs model I/O.
|
|
61
|
+
The provider performs model I/O. `LittleGhost::ModelResolver` resolves application intent into a `LittleGhost::Model`, which carries the provider, target, settings, details, and role for a run.
|
|
42
62
|
|
|
43
63
|
## Agents declare behavior
|
|
44
64
|
|
|
@@ -56,7 +76,7 @@ end
|
|
|
56
76
|
|
|
57
77
|
The class-level DSL is inheritable. It can declare prompts, limits, callbacks, tool classes, structured results, context management, skills, and delegation. A capability mixin may be included in `LittleGhost::Agent`, but its behavior remains inactive until the corresponding DSL is called.
|
|
58
78
|
|
|
59
|
-
`CustomerSupportAgent.ask` creates a standalone
|
|
79
|
+
`CustomerSupportAgent.ask` creates a standalone entrypoint, builds and consumes a `LittleGhost::Run`, and returns that run. `CustomerSupportAgent.stream_ask` creates the same kind of entrypoint and yields the run's events. Create `CustomerSupportAgent.new(runtime:)` explicitly when several calls should reuse one runtime. Agents built by a runtime are instead scoped to their owning run and return a `LittleGhost::RunResult` from `#call`.
|
|
60
80
|
|
|
61
81
|
That distinction explains two useful return paths:
|
|
62
82
|
|
|
@@ -195,9 +215,9 @@ Streams expose generic framework events rather than provider wire formats. Consu
|
|
|
195
215
|
|
|
196
216
|
The core design can be summarized as four choices:
|
|
197
217
|
|
|
198
|
-
- Put shared construction and provider policy in configuration
|
|
218
|
+
- Put shared construction and provider policy in configuration; use inline declarations or independent YAML files according to the application's needs.
|
|
199
219
|
- Put model behavior and available capabilities on agent classes.
|
|
200
220
|
- Put privileged application operations behind narrow, authorized tools.
|
|
201
221
|
- Put mandatory ordering in workflows; leave optional delegation to subagents.
|
|
202
222
|
|
|
203
|
-
Return to [Getting Started](
|
|
223
|
+
Return to [Getting Started](getting_started.md) for the complete first-run setup. The API reference covers exact signatures and lifecycle details for `LittleGhost::Runtime`, `LittleGhost::Run`, `LittleGhost::Agent`, `LittleGhost::Tool`, `LittleGhost::Workflow`, and `LittleGhost::ModelResolver`.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Getting Started with LittleGhost
|
|
2
|
+
|
|
3
|
+
This guide builds a customer support agent that checks a small help center before answering. It focuses on the Ruby objects needed for one useful run: a tool, an agent, and the call that starts it.
|
|
4
|
+
|
|
5
|
+
LittleGhost runs inside your Ruby process. It does not choose how your application is hosted or where these definitions live.
|
|
6
|
+
|
|
7
|
+
## Install LittleGhost
|
|
8
|
+
|
|
9
|
+
LittleGhost requires Ruby 3.3 or newer. Add the gem to your `Gemfile`:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "little_ghost"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Install the bundle and set a provider credential:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
$ bundle install
|
|
19
|
+
$ export OPENAI_API_KEY="..."
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
With `OPENAI_API_KEY` present, LittleGhost can connect the `openai` provider name used below. OpenRouter credentials work as well. Use application secret management outside a local shell, and do not commit provider credentials.
|
|
23
|
+
|
|
24
|
+
## Give the agent a tool
|
|
25
|
+
|
|
26
|
+
Start by requiring LittleGhost and defining a narrow help center lookup:
|
|
27
|
+
|
|
28
|
+
```ruby
|
|
29
|
+
require "little_ghost"
|
|
30
|
+
|
|
31
|
+
class HelpCenterLookupTool < LittleGhost::Tool
|
|
32
|
+
HELP_CENTER_ENTRIES = {
|
|
33
|
+
"refunds" => "Refunds are available within 30 days of purchase.",
|
|
34
|
+
"shipping" => "Standard shipping takes three to five business days."
|
|
35
|
+
}.freeze
|
|
36
|
+
|
|
37
|
+
description "Look up a help center entry by topic."
|
|
38
|
+
input_schema(
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
topic: {type: "string", enum: HELP_CENTER_ENTRIES.keys}
|
|
42
|
+
},
|
|
43
|
+
required: ["topic"],
|
|
44
|
+
additionalProperties: false
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def call(input)
|
|
48
|
+
HELP_CENTER_ENTRIES.fetch(input.fetch("topic"))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
A tool gives the model one application operation with a name, description, and validated JSON input. LittleGhost validates the input before calling `#call` and turns the returned value into model context.
|
|
54
|
+
|
|
55
|
+
The schema checks shape, not authorization. A tool that reads customer data or performs an action must enforce the application's trust rules inside its implementation.
|
|
56
|
+
|
|
57
|
+
## Define the agent
|
|
58
|
+
|
|
59
|
+
Now describe the agent's behavior and make the lookup available to it:
|
|
60
|
+
|
|
61
|
+
```ruby
|
|
62
|
+
class CustomerSupportAgent < LittleGhost::Agent
|
|
63
|
+
description "Answers customer support questions."
|
|
64
|
+
model "openai:gpt-5.6-luna"
|
|
65
|
+
system_prompt <<~PROMPT
|
|
66
|
+
Answer clearly and do not invent company guidance.
|
|
67
|
+
Use the help center lookup tool before stating company guidance.
|
|
68
|
+
PROMPT
|
|
69
|
+
|
|
70
|
+
tools HelpCenterLookupTool
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
An agent class is a reusable behavior definition. It owns its prompt, tools, model selection, limits, and other capabilities. This agent names an OpenAI connection and model directly, so the first example does not need a separate model profile.
|
|
75
|
+
|
|
76
|
+
## Ask a question
|
|
77
|
+
|
|
78
|
+
Call the agent class to run one request to completion:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
run = CustomerSupportAgent.ask(
|
|
82
|
+
"I bought an item two weeks ago. Can I get a refund?"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if run.completed?
|
|
86
|
+
puts run.response
|
|
87
|
+
else
|
|
88
|
+
warn "Support request ended as #{run.outcome}: #{run.error&.class}"
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`CustomerSupportAgent.ask` creates and consumes a `LittleGhost::Run`. A successful run exposes its final text through `#response`; it also retains the normalized result, outcome, usage, messages, and any terminal error.
|
|
93
|
+
|
|
94
|
+
The model can call `HelpCenterLookupTool` with `{"topic":"refunds"}` and answer along these lines:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
Refunds are available within 30 days, so a purchase from two weeks ago is eligible.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Model wording and tool selection are not deterministic. The prompt directs the agent to ground company guidance in the validated lookup; applications that must enforce a lookup should put that ordering in a workflow.
|
|
101
|
+
|
|
102
|
+
## Stream the same agent
|
|
103
|
+
|
|
104
|
+
Use `.stream_ask` when a console, HTTP response, or user interface should receive progress while the run is active:
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
CustomerSupportAgent.stream_ask("Can I get a refund?").each do |event|
|
|
108
|
+
case event.type
|
|
109
|
+
when :text_delta
|
|
110
|
+
print event.data.fetch(:text)
|
|
111
|
+
when :run_error
|
|
112
|
+
warn event.data.fetch(:message)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The stream yields `LittleGhost::StreamEvent` objects. Text, tool activity, usage, traces, and terminal lifecycle facts share this interface, so callers do not need provider-specific response handling.
|
|
118
|
+
|
|
119
|
+
Both calls use the same agent definition and active LittleGhost configuration. Core Concepts explains reusable runtimes when an application needs more control over shared services.
|
|
120
|
+
|
|
121
|
+
## Add a model role when the application grows
|
|
122
|
+
|
|
123
|
+
Direct targets keep a small application easy to read. A larger application can give the same selection a stable role, then change the underlying provider, model, and defaults without editing each agent class:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
LittleGhost.configure do |config|
|
|
127
|
+
config.providers = {
|
|
128
|
+
openai: {adapter: :openai, api_key: ENV.fetch("OPENAI_API_KEY")}
|
|
129
|
+
}
|
|
130
|
+
config.models = {
|
|
131
|
+
customer_support: {
|
|
132
|
+
target: "openai:gpt-5.6-luna",
|
|
133
|
+
settings: {temperature: 0.2}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
config.default_model = :customer_support
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
class CustomerSupportAgent < LittleGhost::Agent
|
|
140
|
+
model :customer_support
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
An agent may also keep a small amount of model-specific configuration beside its behavior:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
class DeliberateSupportAgent < LittleGhost::Agent
|
|
148
|
+
model(
|
|
149
|
+
provider: "openai",
|
|
150
|
+
model: "gpt-5.6-luna",
|
|
151
|
+
reasoning_effort: "high"
|
|
152
|
+
)
|
|
153
|
+
end
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Here, `provider` names a configured connection and every other key after `model` is a trusted model setting. Provider connections and model profiles may instead come from independent YAML files under `config/little_ghost`, or from paths selected in `LittleGhost.configure`. Inline declarations take precedence over explicit paths, which take precedence over conventional files; environment-based selection and the built-in default are the final fallback. `LittleGhost::Agent` and `LittleGhost::Configuration` document the complete shapes and precedence.
|
|
157
|
+
|
|
158
|
+
## Fit LittleGhost into your application
|
|
159
|
+
|
|
160
|
+
LittleGhost does not require an application layout. Keep agents and tools beside related application code when your framework or loader already has a home for them. If you want LittleGhost to eager-load these definitions, `app/agents` and `app/tools` are available conventions, and every lookup path is configurable.
|
|
161
|
+
|
|
162
|
+
Hosting remains the surrounding application's responsibility. A Rails controller, Rack endpoint, background job, CLI, or another Ruby entrypoint can call the same agent APIs shown above.
|
|
163
|
+
|
|
164
|
+
Read [Core Concepts](core_concepts.md) next for model selection, reusable runtimes, subagents, workflows, sessions, and the boundaries between them. The API reference covers exact signatures for `LittleGhost::Agent`, `LittleGhost::Tool`, `LittleGhost::Configuration`, and `LittleGhost::Run`.
|
|
@@ -9,7 +9,7 @@ module LittleGhost
|
|
|
9
9
|
# Adapter turns a LittleGhost stream into AG-UI event hashes. It lets a Ruby
|
|
10
10
|
# agent drive compatible chat interfaces without changing the agent itself.
|
|
11
11
|
#
|
|
12
|
-
# events = CustomerSupportAgent.
|
|
12
|
+
# events = CustomerSupportAgent.stream_ask("Where is my order?")
|
|
13
13
|
# adapter = LittleGhost::AGUI::Adapter.new
|
|
14
14
|
# adapter.stream(events, thread_id: "thread-1", run_id: "run-1").each do |event|
|
|
15
15
|
# websocket.write(JSON.generate(event))
|
|
@@ -259,10 +259,7 @@ module LittleGhost
|
|
|
259
259
|
end
|
|
260
260
|
|
|
261
261
|
def model_context_window_tokens(configuration)
|
|
262
|
-
value = model.
|
|
263
|
-
model.metadata[:context_window_tokens] || model.metadata["context_window_tokens"] ||
|
|
264
|
-
model.metadata[:context_window] || model.metadata["context_window"]
|
|
265
|
-
)
|
|
262
|
+
value = model.details.context_window
|
|
266
263
|
value = Integer(value) if value
|
|
267
264
|
value&.positive? ? value : configuration.fetch(:context_window_tokens)
|
|
268
265
|
rescue ArgumentError, TypeError
|