glove-foundry 0.3.2 → 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.
- package/README.md +195 -4
- package/dist/{chunk-P65RT7H5.js → chunk-25BGNRJN.js} +1452 -178
- package/dist/{chunk-CRWY7M66.js → chunk-5LDW2N2E.js} +1086 -91
- package/dist/{chunk-3GCUECPA.js → chunk-GKZLWD5M.js} +66 -2
- package/dist/cli.js +186 -40
- package/dist/{client-CLkZREDr.d.ts → client-D0-pKEZM.d.ts} +365 -12
- package/dist/client.d.ts +4 -1
- package/dist/client.js +1 -1
- package/dist/config.d.ts +15 -1
- package/dist/execution-agent.js +1 -1
- package/dist/index.d.ts +91 -5
- package/dist/index.js +428 -6
- package/docs/architecture.md +51 -0
- package/docs/building-with-foundry.md +336 -4
- package/docs/evaluation-checklist.md +10 -1
- package/docs/guidance.md +146 -0
- package/docs/inspector.md +39 -1
- package/docs/release-verification.md +74 -0
- package/package.json +14 -12
- package/templates/minimal/README.md +30 -2
- package/templates/travel-concierge/README.md +33 -5
package/README.md
CHANGED
|
@@ -6,16 +6,94 @@ Glove Foundry is an Effect-native application framework for typed, observable Gl
|
|
|
6
6
|
|
|
7
7
|
The development server includes a hierarchical inspector for definitions, instances, runs, automations, integrations, and shared workspaces. See the [inspector guide](./docs/inspector.md).
|
|
8
8
|
|
|
9
|
+
Build guided conversations with first-class, lazy `goals`, `facts`, `forms`, and
|
|
10
|
+
`contextProviders`. Native runners own behavior; adapters own saved progress,
|
|
11
|
+
evidence and answers. See [the guidance handbook](./docs/guidance.md) for scope,
|
|
12
|
+
durable SQLite setup, preparation, and a runnable example.
|
|
13
|
+
|
|
14
|
+
## Your first agent application
|
|
15
|
+
|
|
16
|
+
Dependency installation is selected by default in the setup wizard. Foundry runs
|
|
17
|
+
your chosen package manager's `install` command in the generated project and waits
|
|
18
|
+
for it to finish before showing next steps. In non-interactive commands, add
|
|
19
|
+
`--install` to install automatically; use `--no-install` to defer it explicitly.
|
|
20
|
+
|
|
21
|
+
Use Node.js 22.13+ (recommended, including SQLite memory support); the CLI requires
|
|
22
|
+
at least Node 20.12. Run this in a terminal:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx glove-foundry init
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The Clack-powered setup guides you through a project directory, standalone or
|
|
29
|
+
Next.js integration, a starter, and your package manager. Review the plan before
|
|
30
|
+
any files are created. Arrow keys move, Enter selects, and Ctrl+C cancels. It never
|
|
31
|
+
asks for API keys. Installing dependencies is an explicit choice.
|
|
32
|
+
|
|
33
|
+
Choose **Guided example** for a first look: its travel concierge works without a
|
|
34
|
+
provider key. Choose **Minimal agent** when you want one agent and one tool and are
|
|
35
|
+
ready to configure OpenRouter. These are development starters, not durable storage
|
|
36
|
+
or preconfigured Telegram/Discord deployments.
|
|
37
|
+
|
|
38
|
+
For a repeatable, non-interactive setup:
|
|
39
|
+
|
|
9
40
|
```bash
|
|
10
|
-
npx glove-foundry init my-agent-app
|
|
41
|
+
npx glove-foundry init my-agent-app --template travel-concierge --package-manager pnpm --yes
|
|
11
42
|
cd my-agent-app
|
|
12
43
|
pnpm install
|
|
13
44
|
pnpm dev
|
|
14
45
|
```
|
|
15
46
|
|
|
47
|
+
Open `http://127.0.0.1:4141`, choose **Start a run**, select the concierge, and ask
|
|
48
|
+
“Find a flight to Nairobi.” Open that run to follow its model and tool events. Edit
|
|
49
|
+
`agents/concierge/agent.ts` to change behavior; the development server reloads it.
|
|
50
|
+
Run `pnpm typecheck` and `pnpm lint` after changes.
|
|
51
|
+
|
|
52
|
+
For live model responses, copy `.env.example` to `.env.local`, set
|
|
53
|
+
`OPENROUTER_API_KEY`, and restart `pnpm dev`. Keep that file out of version control.
|
|
54
|
+
The guided example stays in deterministic demo mode until a key is configured.
|
|
55
|
+
|
|
56
|
+
### Initializer options
|
|
57
|
+
|
|
58
|
+
| Option | Meaning |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `--template travel-concierge\|minimal` | Choose a worked example or small starting point |
|
|
61
|
+
| `--target standalone\|nextjs` | Create a project or add agents to an existing app; Next.js is detected |
|
|
62
|
+
| `--package-manager pnpm\|npm\|yarn\|bun` | Choose install commands; existing lockfiles are detected |
|
|
63
|
+
| `--yes` or `--no-interactive` | Accept defaults without prompts; does not install unless `--install` is supplied |
|
|
64
|
+
| `--interactive` | Require a terminal; useful when accidental piping should fail |
|
|
65
|
+
| `--install` or `--no-install` | Install dependencies now, or print the command for later |
|
|
66
|
+
| `--help` | Show create and runtime command help |
|
|
67
|
+
|
|
68
|
+
Piped commands never wait for a prompt. Existing standalone directories must be
|
|
69
|
+
empty; Next.js integration preserves existing app files and refuses collisions.
|
|
70
|
+
If installation fails, your generated project remains available with retry steps.
|
|
71
|
+
|
|
72
|
+
### Before deploying
|
|
73
|
+
|
|
74
|
+
Persist **three separate things**: Foundry instance/activation data, Glove
|
|
75
|
+
conversation history, and structured memory/VFS state. The demo's in-memory
|
|
76
|
+
adapters intentionally reset and must not be mistaken for production persistence.
|
|
77
|
+
Use `FileFoundryDataAdapter` for single-host runtime data, a durable conversation
|
|
78
|
+
store, and `glove-memory/sqlite` or your own native memory adapters. Add VFS
|
|
79
|
+
persistence when agents work on documents. Multi-host deployments need shared,
|
|
80
|
+
transactional adapters. See [Building with Foundry](./docs/building-with-foundry.md).
|
|
81
|
+
|
|
82
|
+
**Troubleshooting:** check `node --version` for engine errors, add a provider key
|
|
83
|
+
for the minimal starter, choose another `--port` if 4141 is occupied, and inspect a
|
|
84
|
+
failed run's events for provider failures. With npm, use `npm run dev` instead of
|
|
85
|
+
`pnpm dev`; generated README commands follow your selected package manager.
|
|
86
|
+
|
|
16
87
|
Inside an installed project, the framework binary also supports `glove foundry dev`
|
|
17
88
|
and `glove foundry start`.
|
|
18
89
|
|
|
90
|
+
Foundry binds to loopback by default. A non-loopback host fails closed unless the
|
|
91
|
+
application supplies `requestAuthorization`, an Effect-native adapter that returns
|
|
92
|
+
only an authorization decision. It may validate bearer/basic credentials, cookies,
|
|
93
|
+
or an identity from a trusted proxy; Foundry never stores or observes the credential.
|
|
94
|
+
The typed client accepts a matching per-request `authorization` adapter. Terminate
|
|
95
|
+
TLS and apply rate/network policy at the deployment boundary.
|
|
96
|
+
|
|
19
97
|
## The mental model
|
|
20
98
|
|
|
21
99
|
Foundry keeps code and data deliberately separate.
|
|
@@ -116,7 +194,7 @@ Definition config is followed through the imported value. Zod config schemas inf
|
|
|
116
194
|
|
|
117
195
|
## Applications, transmissions, and connections
|
|
118
196
|
|
|
119
|
-
Applications are headless, installable capability definitions. They may own multiple inbound and outbound transmissions. Outbound transmissions become tools only when the application is installed on an instance.
|
|
197
|
+
Applications are headless, installable capability definitions. They may own multiple inbound and outbound transmissions. Outbound transmissions become tools only when the application is installed on an instance. Calling one of those tools awaits and returns the outbound adapter's schema-validated result; grants, credentials, and adapter execution remain in the parent runtime. Set `outbound.requiresPermission` to a boolean or payload predicate for exact-input approval. `outbound.project` can remove presentation-only material from model-visible data, while `outbound.render` retains a UI-only projection in tool history—for example, a browser screenshot can render without copying its base64 bytes into model context. Framework-authored fire-and-forget transmissions keep their asynchronous command semantics.
|
|
120
198
|
|
|
121
199
|
```ts
|
|
122
200
|
// connections/provider-events.connection.ts
|
|
@@ -130,6 +208,7 @@ export default defineConnection({
|
|
|
130
208
|
route: chooseRoute(ctx.routes, event),
|
|
131
209
|
eventId: event.id,
|
|
132
210
|
threadKey: event.threadId,
|
|
211
|
+
awaitCompletion: true,
|
|
133
212
|
raw: event,
|
|
134
213
|
}))
|
|
135
214
|
}),
|
|
@@ -138,6 +217,13 @@ export default defineConnection({
|
|
|
138
217
|
|
|
139
218
|
Foundry supervises connection lifetime and retry, but never acquires or refreshes credentials. Account references contain only metadata and an opaque `accessRef`. Your `accountSessions` or provider adapter owns credential material and refresh.
|
|
140
219
|
|
|
220
|
+
`receive()` resolves after durable dispatch by default. A stateful consumer that
|
|
221
|
+
awaits each event in order can set `awaitCompletion: true`; its Effect then remains
|
|
222
|
+
open until every matching run is terminal, preventing successive chat turns from
|
|
223
|
+
racing one transcript. Leave it unset for dispatch-oriented streams or manage a
|
|
224
|
+
per-conversation queue in a transport that needs unrelated threads to proceed in
|
|
225
|
+
parallel.
|
|
226
|
+
|
|
141
227
|
Connections are desired only when:
|
|
142
228
|
|
|
143
229
|
- an instance has installed the application and has a matching inbound playbook; or
|
|
@@ -145,6 +231,31 @@ Connections are desired only when:
|
|
|
145
231
|
|
|
146
232
|
This covers webhook/socket ingestion and long-lived provider bots without exposing the execution backend as a framework primitive.
|
|
147
233
|
|
|
234
|
+
MCP entries can resolve lazily from typed installation data in the same way. The instance owns the selected URL, metadata, and tool exclusions; the agent-owned `mcpAdapter` receives the decoded selections and resolves fresh auth headers only when `glove-mcp` connects.
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
const projectMcp = defineMcp({
|
|
238
|
+
description: "Instance-selected project MCP",
|
|
239
|
+
config: z.object({
|
|
240
|
+
serverUrl: z.string().url(),
|
|
241
|
+
tokenEnvironment: z.string(),
|
|
242
|
+
}),
|
|
243
|
+
entry: ({ config }) => ({
|
|
244
|
+
name: "Project tools",
|
|
245
|
+
description: "Project-specific capabilities",
|
|
246
|
+
url: config.serverUrl,
|
|
247
|
+
}),
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
export default defineAgent({
|
|
251
|
+
// ...
|
|
252
|
+
mcpAdapter: ({ resolved, conversationId }) =>
|
|
253
|
+
Effect.succeed(mcpAdapterFor(conversationId, resolved)),
|
|
254
|
+
})
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Credential acquisition and refresh still belong to `mcpAdapterFor`; persisted installation config should contain only a reference such as an environment-variable or vault-record name.
|
|
258
|
+
|
|
148
259
|
## Background playbooks and lazy provisioning
|
|
149
260
|
|
|
150
261
|
A playbook is serializable runtime policy. It is composed by an agent resolver or frontend from transmission primitives, then persisted on the instance. Executable normalization, authentication, predicates, serialization, and delivery live on the transmission definition.
|
|
@@ -174,7 +285,80 @@ The data adapter atomically enforces `provisioningKey`. Inbound delivery claims
|
|
|
174
285
|
|
|
175
286
|
## Conversations and shared work
|
|
176
287
|
|
|
177
|
-
One agent instance can own many conversations.
|
|
288
|
+
One agent instance can own many conversations. Messages use native Glove content parts,
|
|
289
|
+
and media parts may retain an optional human-facing filename. The server keeps JSON at
|
|
290
|
+
a conservative 1 MB by default; a trusted multimodal deployment can set the typed
|
|
291
|
+
`server.messageBodyBytes` bound for larger base64 messages. Foundry also provides
|
|
292
|
+
adapter-backed workspace entries, shared inbox items, tasks, and scoped environment
|
|
293
|
+
values. These are data primitives, not prompt conventions, so agents can pass documents
|
|
294
|
+
and work records by reference instead of copying context.
|
|
295
|
+
|
|
296
|
+
The built-in **Chat** page is a durable WebChat surface over those same primitives.
|
|
297
|
+
It lists conversations per runtime instance, reloads exact native Glove history from
|
|
298
|
+
the configured `store`/`conversationStore`, accepts text and file content parts, and
|
|
299
|
+
supports cancel plus interrupt-and-restart steering. The typed client exposes the
|
|
300
|
+
same read boundary:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
const transcript = await foundry.conversationTranscript(agent.id, conversation.id, {
|
|
304
|
+
limit: 100,
|
|
305
|
+
})
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`transcript.persisted` is `false` when the agent has no configured conversation
|
|
309
|
+
store. Foundry does not fabricate history from retained runs or UI state.
|
|
310
|
+
|
|
311
|
+
## Least-privilege subagents
|
|
312
|
+
|
|
313
|
+
Subagents may declare fixed tools or project an invocation-time subset from the
|
|
314
|
+
fully assembled parent. That lets a delegate inherit an installed application or
|
|
315
|
+
MCP read operation without receiving the parent's write/admin surface. The
|
|
316
|
+
projection is resolved only when the subagent is called, after instance
|
|
317
|
+
installations and message-dependent assembly have completed.
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
defineSubagent({
|
|
321
|
+
name: "researcher",
|
|
322
|
+
description: "Research one bounded question",
|
|
323
|
+
systemPrompt: "Return evidence, uncertainty, and a concise conclusion.",
|
|
324
|
+
tools: ({ parent }) => projectTools(parent, [
|
|
325
|
+
webSearchToolName,
|
|
326
|
+
webReadToolName,
|
|
327
|
+
"workspace_read_file",
|
|
328
|
+
]),
|
|
329
|
+
})
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
The child keeps its isolated store, compaction policy, model, prompt, skills,
|
|
333
|
+
layers, and subscribers. Parent subscribers still receive the subagent lifecycle
|
|
334
|
+
bracket, so delegation remains visible in the same run trace.
|
|
335
|
+
|
|
336
|
+
## Programmatic tool workflows
|
|
337
|
+
|
|
338
|
+
`defineRepl` can expose an explicit projection of the fully assembled agent as
|
|
339
|
+
sandbox functions. This lets an agent use one Python, JavaScript, or Lisp program
|
|
340
|
+
to read, filter, loop, branch, and invoke several approved capabilities while
|
|
341
|
+
only the final value enters its conversation context:
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
defineRepl({
|
|
345
|
+
language: "python",
|
|
346
|
+
session: PySession.create({ actor: agentId }),
|
|
347
|
+
mount: { frame: "workflow", discovery: "auto" },
|
|
348
|
+
programmaticTools: {
|
|
349
|
+
maxCalls: 50,
|
|
350
|
+
select: ({ tools }) => tools
|
|
351
|
+
.filter((tool) => tool.name.startsWith("workspace_"))
|
|
352
|
+
.map((tool) => ({ tool, server: "workspace" })),
|
|
353
|
+
},
|
|
354
|
+
})
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Selection happens after dynamic installations and `configure`; returned entries
|
|
358
|
+
carry direct live tool references rather than parallel ids. The surface is empty
|
|
359
|
+
unless the definition opts in. Foundry revalidates Zod inputs, propagates aborts,
|
|
360
|
+
records safe per-call events, and refuses permission-gated calls inside the
|
|
361
|
+
program so an interactive approval cannot be bypassed.
|
|
178
362
|
|
|
179
363
|
## Immediate work, future work, and sleep
|
|
180
364
|
|
|
@@ -209,12 +393,19 @@ Useful endpoints:
|
|
|
209
393
|
GET /api/manifest
|
|
210
394
|
GET /api/agent-instances
|
|
211
395
|
PATCH /api/agent-instances/:id
|
|
396
|
+
GET /api/conversations/:id/messages?agent=:agentId
|
|
397
|
+
POST /api/conversations/:id/messages
|
|
398
|
+
PATCH /api/conversations/:id
|
|
212
399
|
GET /api/playbook-subscriptions
|
|
213
400
|
PUT /api/playbook-subscriptions
|
|
214
401
|
GET /api/application-connections
|
|
215
402
|
POST /api/transmissions/:routeId/fire
|
|
216
403
|
GET /api/runs
|
|
217
404
|
GET /api/events
|
|
405
|
+
GET /v1/models
|
|
406
|
+
POST /v1/chat/completions
|
|
218
407
|
```
|
|
219
408
|
|
|
220
|
-
|
|
409
|
+
The `/v1/chat/completions` endpoint accepts an agent instance id as `model`, supports SSE streaming, and returns `x-foundry-conversation-id`. Reuse `user`, `conversation_id`, or that header to continue the same durable Foundry conversation from an OpenAI-compatible client.
|
|
410
|
+
|
|
411
|
+
See [Building with Foundry](./docs/building-with-foundry.md), [Architecture](./docs/architecture.md), the compact [`examples/foundry-agent`](../../examples/foundry-agent), and the [Braind Storm workforce](../../examples/foundry-braind-storm).
|