@roackb2/heddle 0.0.7 → 0.0.8
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 +120 -2
- package/dist/examples/heartbeat.d.ts +2 -0
- package/dist/examples/heartbeat.d.ts.map +1 -0
- package/dist/examples/heartbeat.js +61 -0
- package/dist/examples/heartbeat.js.map +1 -0
- package/dist/examples/programmatic-loop.d.ts +2 -0
- package/dist/examples/programmatic-loop.d.ts.map +1 -0
- package/dist/examples/programmatic-loop.js +126 -0
- package/dist/examples/programmatic-loop.js.map +1 -0
- package/dist/src/cli/ask.d.ts.map +1 -1
- package/dist/src/cli/ask.js +10 -41
- package/dist/src/cli/ask.js.map +1 -1
- package/dist/src/cli/chat/hooks/useAgentRun.d.ts.map +1 -1
- package/dist/src/cli/chat/hooks/useAgentRun.js +14 -25
- package/dist/src/cli/chat/hooks/useAgentRun.js.map +1 -1
- package/dist/src/cli/chat/utils/runtime.d.ts.map +1 -1
- package/dist/src/cli/chat/utils/runtime.js +3 -19
- package/dist/src/cli/chat/utils/runtime.js.map +1 -1
- package/dist/src/cli/main.js +0 -0
- package/dist/src/index.d.ts +12 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/llm/factory.d.ts +1 -1
- package/dist/src/llm/factory.d.ts.map +1 -1
- package/dist/src/llm/factory.js +2 -19
- package/dist/src/llm/factory.js.map +1 -1
- package/dist/src/llm/providers.d.ts +3 -0
- package/dist/src/llm/providers.d.ts.map +1 -0
- package/dist/src/llm/providers.js +21 -0
- package/dist/src/llm/providers.js.map +1 -0
- package/dist/src/runtime/agent-loop.d.ts +42 -0
- package/dist/src/runtime/agent-loop.d.ts.map +1 -0
- package/dist/src/runtime/agent-loop.js +118 -0
- package/dist/src/runtime/agent-loop.js.map +1 -0
- package/dist/src/runtime/api-keys.d.ts +8 -0
- package/dist/src/runtime/api-keys.d.ts.map +1 -0
- package/dist/src/runtime/api-keys.js +25 -0
- package/dist/src/runtime/api-keys.js.map +1 -0
- package/dist/src/runtime/default-tools.d.ts +12 -0
- package/dist/src/runtime/default-tools.d.ts.map +1 -0
- package/dist/src/runtime/default-tools.js +40 -0
- package/dist/src/runtime/default-tools.js.map +1 -0
- package/dist/src/runtime/events.d.ts +62 -0
- package/dist/src/runtime/events.d.ts.map +1 -0
- package/dist/src/runtime/events.js +30 -0
- package/dist/src/runtime/events.js.map +1 -0
- package/dist/src/runtime/heartbeat-store.d.ts +20 -0
- package/dist/src/runtime/heartbeat-store.d.ts.map +1 -0
- package/dist/src/runtime/heartbeat-store.js +42 -0
- package/dist/src/runtime/heartbeat-store.js.map +1 -0
- package/dist/src/runtime/heartbeat.d.ts +39 -0
- package/dist/src/runtime/heartbeat.d.ts.map +1 -0
- package/dist/src/runtime/heartbeat.js +72 -0
- package/dist/src/runtime/heartbeat.js.map +1 -0
- package/dist/src/utils/logger.d.ts.map +1 -1
- package/dist/src/utils/logger.js +2 -2
- package/dist/src/utils/logger.js.map +1 -1
- package/package.json +18 -2
- package/dist/src/__tests__/chat-activity-format.test.d.ts +0 -2
- package/dist/src/__tests__/chat-activity-format.test.d.ts.map +0 -1
- package/dist/src/__tests__/chat-activity-format.test.js +0 -41
- package/dist/src/__tests__/chat-activity-format.test.js.map +0 -1
- package/dist/src/__tests__/chat-compaction.test.d.ts +0 -2
- package/dist/src/__tests__/chat-compaction.test.d.ts.map +0 -1
- package/dist/src/__tests__/chat-compaction.test.js +0 -63
- package/dist/src/__tests__/chat-compaction.test.js.map +0 -1
- package/dist/src/__tests__/chat-format.test.d.ts +0 -2
- package/dist/src/__tests__/chat-format.test.d.ts.map +0 -1
- package/dist/src/__tests__/chat-format.test.js +0 -137
- package/dist/src/__tests__/chat-format.test.js.map +0 -1
- package/dist/src/__tests__/chat-runtime.test.d.ts +0 -2
- package/dist/src/__tests__/chat-runtime.test.d.ts.map +0 -1
- package/dist/src/__tests__/chat-runtime.test.js +0 -39
- package/dist/src/__tests__/chat-runtime.test.js.map +0 -1
- package/dist/src/__tests__/core-utils.test.d.ts +0 -2
- package/dist/src/__tests__/core-utils.test.d.ts.map +0 -1
- package/dist/src/__tests__/core-utils.test.js +0 -87
- package/dist/src/__tests__/core-utils.test.js.map +0 -1
- package/dist/src/__tests__/file-mentions.test.d.ts +0 -2
- package/dist/src/__tests__/file-mentions.test.d.ts.map +0 -1
- package/dist/src/__tests__/file-mentions.test.js +0 -29
- package/dist/src/__tests__/file-mentions.test.js.map +0 -1
- package/dist/src/__tests__/llm-factory.test.d.ts +0 -2
- package/dist/src/__tests__/llm-factory.test.d.ts.map +0 -1
- package/dist/src/__tests__/llm-factory.test.js +0 -45
- package/dist/src/__tests__/llm-factory.test.js.map +0 -1
- package/dist/src/__tests__/local-commands.test.d.ts +0 -2
- package/dist/src/__tests__/local-commands.test.d.ts.map +0 -1
- package/dist/src/__tests__/local-commands.test.js +0 -153
- package/dist/src/__tests__/local-commands.test.js.map +0 -1
- package/dist/src/__tests__/project-approval-rules.test.d.ts +0 -2
- package/dist/src/__tests__/project-approval-rules.test.d.ts.map +0 -1
- package/dist/src/__tests__/project-approval-rules.test.js +0 -135
- package/dist/src/__tests__/project-approval-rules.test.js.map +0 -1
- package/dist/src/__tests__/prompt-input.test.d.ts +0 -2
- package/dist/src/__tests__/prompt-input.test.d.ts.map +0 -1
- package/dist/src/__tests__/prompt-input.test.js +0 -57
- package/dist/src/__tests__/prompt-input.test.js.map +0 -1
- package/dist/src/__tests__/prompts.test.d.ts +0 -2
- package/dist/src/__tests__/prompts.test.d.ts.map +0 -1
- package/dist/src/__tests__/prompts.test.js +0 -46
- package/dist/src/__tests__/prompts.test.js.map +0 -1
- package/dist/src/__tests__/run-agent.test.d.ts +0 -2
- package/dist/src/__tests__/run-agent.test.d.ts.map +0 -1
- package/dist/src/__tests__/run-agent.test.js +0 -1276
- package/dist/src/__tests__/run-agent.test.js.map +0 -1
- package/dist/src/__tests__/run-shell.command.test.d.ts +0 -2
- package/dist/src/__tests__/run-shell.command.test.d.ts.map +0 -1
- package/dist/src/__tests__/run-shell.command.test.js +0 -188
- package/dist/src/__tests__/run-shell.command.test.js.map +0 -1
- package/dist/src/__tests__/smoke.test.d.ts +0 -2
- package/dist/src/__tests__/smoke.test.d.ts.map +0 -1
- package/dist/src/__tests__/smoke.test.js +0 -314
- package/dist/src/__tests__/smoke.test.js.map +0 -1
- package/dist/src/__tests__/tools.test.d.ts +0 -2
- package/dist/src/__tests__/tools.test.d.ts.map +0 -1
- package/dist/src/__tests__/tools.test.js +0 -698
- package/dist/src/__tests__/tools.test.js.map +0 -1
- package/dist/src/__tests__/trace-format.test.d.ts +0 -2
- package/dist/src/__tests__/trace-format.test.d.ts.map +0 -1
- package/dist/src/__tests__/trace-format.test.js +0 -148
- package/dist/src/__tests__/trace-format.test.js.map +0 -1
- package/dist/src/cli/chat/actions.d.ts +0 -47
- package/dist/src/cli/chat/actions.d.ts.map +0 -1
- package/dist/src/cli/chat/actions.js +0 -215
- package/dist/src/cli/chat/actions.js.map +0 -1
- package/dist/src/cli/chat/format.d.ts +0 -23
- package/dist/src/cli/chat/format.d.ts.map +0 -1
- package/dist/src/cli/chat/format.js +0 -243
- package/dist/src/cli/chat/format.js.map +0 -1
- package/dist/src/cli/chat/local-commands.d.ts +0 -17
- package/dist/src/cli/chat/local-commands.d.ts.map +0 -1
- package/dist/src/cli/chat/local-commands.js +0 -180
- package/dist/src/cli/chat/local-commands.js.map +0 -1
- package/dist/src/cli/chat/panels.d.ts +0 -37
- package/dist/src/cli/chat/panels.d.ts.map +0 -1
- package/dist/src/cli/chat/panels.js +0 -142
- package/dist/src/cli/chat/panels.js.map +0 -1
- package/dist/src/cli/chat/runtime.d.ts +0 -26
- package/dist/src/cli/chat/runtime.d.ts.map +0 -1
- package/dist/src/cli/chat/runtime.js +0 -28
- package/dist/src/cli/chat/runtime.js.map +0 -1
- package/dist/src/cli/chat/storage.d.ts +0 -13
- package/dist/src/cli/chat/storage.d.ts.map +0 -1
- package/dist/src/cli/chat/storage.js +0 -126
- package/dist/src/cli/chat/storage.js.map +0 -1
- package/dist/src/cli/chat/types.d.ts +0 -51
- package/dist/src/cli/chat/types.d.ts.map +0 -1
- package/dist/src/cli/chat/types.js +0 -2
- package/dist/src/cli/chat/types.js.map +0 -1
- package/dist/src/cli/chat/use-run-state.d.ts +0 -23
- package/dist/src/cli/chat/use-run-state.d.ts.map +0 -1
- package/dist/src/cli/chat/use-run-state.js +0 -118
- package/dist/src/cli/chat/use-run-state.js.map +0 -1
- package/dist/src/cli/chat/use-sessions.d.ts +0 -21
- package/dist/src/cli/chat/use-sessions.d.ts.map +0 -1
- package/dist/src/cli/chat/use-sessions.js +0 -111
- package/dist/src/cli/chat/use-sessions.js.map +0 -1
- package/dist/src/cli/chat-actions.d.ts +0 -47
- package/dist/src/cli/chat-actions.d.ts.map +0 -1
- package/dist/src/cli/chat-actions.js +0 -215
- package/dist/src/cli/chat-actions.js.map +0 -1
- package/dist/src/cli/chat-format.d.ts +0 -23
- package/dist/src/cli/chat-format.d.ts.map +0 -1
- package/dist/src/cli/chat-format.js +0 -243
- package/dist/src/cli/chat-format.js.map +0 -1
- package/dist/src/cli/chat-local-commands.d.ts +0 -17
- package/dist/src/cli/chat-local-commands.d.ts.map +0 -1
- package/dist/src/cli/chat-local-commands.js +0 -180
- package/dist/src/cli/chat-local-commands.js.map +0 -1
- package/dist/src/cli/chat-panels.d.ts +0 -37
- package/dist/src/cli/chat-panels.d.ts.map +0 -1
- package/dist/src/cli/chat-panels.js +0 -142
- package/dist/src/cli/chat-panels.js.map +0 -1
- package/dist/src/cli/chat-runtime.d.ts +0 -26
- package/dist/src/cli/chat-runtime.d.ts.map +0 -1
- package/dist/src/cli/chat-runtime.js +0 -28
- package/dist/src/cli/chat-runtime.js.map +0 -1
- package/dist/src/cli/chat-storage.d.ts +0 -13
- package/dist/src/cli/chat-storage.d.ts.map +0 -1
- package/dist/src/cli/chat-storage.js +0 -126
- package/dist/src/cli/chat-storage.js.map +0 -1
- package/dist/src/cli/chat-submit.d.ts +0 -28
- package/dist/src/cli/chat-submit.d.ts.map +0 -1
- package/dist/src/cli/chat-submit.js +0 -90
- package/dist/src/cli/chat-submit.js.map +0 -1
- package/dist/src/cli/chat-types.d.ts +0 -51
- package/dist/src/cli/chat-types.d.ts.map +0 -1
- package/dist/src/cli/chat-types.js +0 -2
- package/dist/src/cli/chat-types.js.map +0 -1
- package/dist/src/cli/chat.d.ts +0 -4
- package/dist/src/cli/chat.d.ts.map +0 -1
- package/dist/src/cli/chat.js +0 -153
- package/dist/src/cli/chat.js.map +0 -1
- package/dist/src/cli/useChatRunState.d.ts +0 -23
- package/dist/src/cli/useChatRunState.d.ts.map +0 -1
- package/dist/src/cli/useChatRunState.js +0 -118
- package/dist/src/cli/useChatRunState.js.map +0 -1
- package/dist/src/cli/useChatSessions.d.ts +0 -21
- package/dist/src/cli/useChatSessions.d.ts.map +0 -1
- package/dist/src/cli/useChatSessions.js +0 -111
- package/dist/src/cli/useChatSessions.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Heddle is a terminal coding agent runtime and CLI.
|
|
|
4
4
|
|
|
5
5
|
It is built to feel like a terminal partner that understands your project, keeps continuity across real work, and becomes more useful over time.
|
|
6
6
|
|
|
7
|
-
It is open source, provider-agnostic, supports OpenAI and Anthropic models, and can build memory across sessions.
|
|
7
|
+
It is open source, provider-agnostic, supports OpenAI and Anthropic models, and can build memory across sessions. For agentic-system builders, Heddle also exposes heartbeat primitives for autonomous wake cycles, checkpointing, and long-running background work.
|
|
8
8
|
|
|
9
9
|
## How Heddle Helps
|
|
10
10
|
|
|
@@ -18,6 +18,9 @@ It is open source, provider-agnostic, supports OpenAI and Anthropic models, and
|
|
|
18
18
|
## Advanced Capabilities
|
|
19
19
|
|
|
20
20
|
- provider-agnostic model support across OpenAI and Anthropic
|
|
21
|
+
- embeddable `runAgentLoop` API for building non-CLI agent hosts
|
|
22
|
+
- `runAgentHeartbeat` for scheduler-driven autonomous wake cycles without chat by default
|
|
23
|
+
- serializable checkpoints for resume, background execution, and hosted workers
|
|
21
24
|
- provider-backed hosted web search through `web_search`
|
|
22
25
|
- local image viewing from referenced file paths through `view_image`
|
|
23
26
|
- inline `@file` mentions that tell the agent which workspace files to inspect first
|
|
@@ -85,6 +88,8 @@ Heddle currently supports:
|
|
|
85
88
|
- automatic conversation compaction so longer chats preserve context instead of growing unbounded
|
|
86
89
|
- manual `/compact` to shrink the current session transcript on demand
|
|
87
90
|
- persistent workspace memory notes under `.heddle/memory/`
|
|
91
|
+
- autonomous heartbeat wake cycles through `runAgentHeartbeat`
|
|
92
|
+
- serializable run checkpoints for programmatic hosts and later continuation
|
|
88
93
|
- short working-plan support through `update_plan` for substantial multi-step tasks
|
|
89
94
|
- remembered per-project approvals for repeated commands and edits
|
|
90
95
|
- interrupt and resume support for longer-running coding workflows
|
|
@@ -98,6 +103,49 @@ The planning workflow is also intentionally lightweight: Heddle does not force a
|
|
|
98
103
|
|
|
99
104
|
The web-search workflow is provider-backed rather than crawler-backed: OpenAI models use OpenAI-hosted web search, and Anthropic models use Anthropic-hosted web search when available through the selected model/tool path.
|
|
100
105
|
|
|
106
|
+
## Heartbeat
|
|
107
|
+
|
|
108
|
+
Heddle exposes `runAgentHeartbeat` for autonomous, scheduler-driven agent work.
|
|
109
|
+
|
|
110
|
+
Heartbeat is not an interactive chat mode. It is a host/runtime primitive for systems that want to wake an agent periodically, let it work within budget and approval limits, checkpoint the result, and decide what should happen next.
|
|
111
|
+
|
|
112
|
+
A heartbeat wake cycle:
|
|
113
|
+
|
|
114
|
+
- loads a durable task plus an optional checkpoint
|
|
115
|
+
- resumes prior transcript state if available
|
|
116
|
+
- lets the agent do bounded useful work without a human prompt
|
|
117
|
+
- checkpoints the new state
|
|
118
|
+
- returns a decision: `continue`, `pause`, `complete`, or `escalate`
|
|
119
|
+
|
|
120
|
+
This is intended for hosted workers, local schedulers, long-running agents, and systems like agent social platforms where agents need to keep working over time without staying in a live chat session.
|
|
121
|
+
|
|
122
|
+
Heartbeat uses a larger default step budget than ordinary short chat runs so a wake cycle has room to inspect, act, and checkpoint. Hosts can still pass `maxSteps` when they need stricter control.
|
|
123
|
+
|
|
124
|
+
Try a small local heartbeat example:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
export OPENAI_API_KEY=your_key_here
|
|
128
|
+
yarn example:heartbeat
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The example stores its checkpoint at `.heddle/examples/heartbeat-demo-checkpoint.json`, so running it again resumes from the previous wake cycle.
|
|
132
|
+
|
|
133
|
+
For hosts that want storage handled by Heddle, use `runStoredHeartbeat` with a checkpoint store:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { createFileHeartbeatCheckpointStore, runStoredHeartbeat } from '@roackb2/heddle'
|
|
137
|
+
|
|
138
|
+
const result = await runStoredHeartbeat({
|
|
139
|
+
task: 'Keep this project moving when safe autonomous progress is available',
|
|
140
|
+
store: createFileHeartbeatCheckpointStore({
|
|
141
|
+
path: '.heddle/heartbeat/project-maintenance.json',
|
|
142
|
+
}),
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// result.nextDelayMs is a scheduling hint. The host still owns the timer,
|
|
146
|
+
// cron job, queue, worker, or hosted scheduler that wakes the agent again.
|
|
147
|
+
```
|
|
148
|
+
|
|
101
149
|
## Knowledge Persistence
|
|
102
150
|
|
|
103
151
|
Heddle can maintain durable workspace knowledge under `.heddle/memory/`.
|
|
@@ -274,9 +322,65 @@ Field notes:
|
|
|
274
322
|
|
|
275
323
|
## Programmatic Use
|
|
276
324
|
|
|
277
|
-
The npm package
|
|
325
|
+
The npm package exports a programmatic execution loop for building other agent hosts on top of Heddle.
|
|
326
|
+
|
|
327
|
+
Use `runAgentLoop` when you want Heddle to assemble the model adapter, default tool bundle, memory tools, and event stream:
|
|
328
|
+
|
|
329
|
+
```ts
|
|
330
|
+
import { runAgentLoop } from '@roackb2/heddle'
|
|
331
|
+
|
|
332
|
+
const result = await runAgentLoop({
|
|
333
|
+
goal: 'Inspect this repo and summarize the main architecture',
|
|
334
|
+
model: 'gpt-5.1-codex',
|
|
335
|
+
workspaceRoot: process.cwd(),
|
|
336
|
+
onEvent(event) {
|
|
337
|
+
// Render progress, persist traces, feed middleware, or bridge into another app.
|
|
338
|
+
console.log(event.type)
|
|
339
|
+
},
|
|
340
|
+
})
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Persist `result.state` or wrap it with `createAgentLoopCheckpoint(result.state)` when another host needs to continue later:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
import { createAgentLoopCheckpoint, runAgentLoop } from '@roackb2/heddle'
|
|
347
|
+
|
|
348
|
+
const checkpoint = createAgentLoopCheckpoint(result.state)
|
|
349
|
+
|
|
350
|
+
await runAgentLoop({
|
|
351
|
+
goal: 'Continue from the prior run and identify the next action',
|
|
352
|
+
resumeFrom: checkpoint,
|
|
353
|
+
})
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The loop emits structured events for:
|
|
357
|
+
|
|
358
|
+
- loop start and finish
|
|
359
|
+
- assistant streaming updates
|
|
360
|
+
- trace events such as tool calls, tool results, approvals, and final outcome
|
|
361
|
+
|
|
362
|
+
The returned result also includes a serializable `state` object with the model, provider, workspace root, outcome, transcript, trace, usage, and timestamps. This is the boundary future hosts can persist for background execution, dashboards, middleware, or heartbeat-style continuation.
|
|
363
|
+
|
|
364
|
+
For autonomous background work, `runAgentHeartbeat` runs one wake cycle from a durable task and optional checkpoint:
|
|
365
|
+
|
|
366
|
+
```ts
|
|
367
|
+
import { runAgentHeartbeat } from '@roackb2/heddle'
|
|
368
|
+
|
|
369
|
+
const heartbeat = await runAgentHeartbeat({
|
|
370
|
+
task: 'Check whether there is safe maintenance work to do for this project',
|
|
371
|
+
checkpoint,
|
|
372
|
+
maxSteps: 8,
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
// Persist heartbeat.checkpoint, then schedule the next wake based on heartbeat.decision.
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Heartbeat is not chat by default. It is meant for scheduler-driven agents that wake up, reload state, do bounded autonomous work, checkpoint, and either continue, pause, complete, or escalate.
|
|
379
|
+
|
|
380
|
+
Lower-level pieces are still exported for custom hosts, including:
|
|
278
381
|
|
|
279
382
|
- `runAgent`
|
|
383
|
+
- `createDefaultAgentTools`
|
|
280
384
|
- LLM adapter helpers
|
|
281
385
|
- built-in tools
|
|
282
386
|
- trace utilities
|
|
@@ -287,6 +391,20 @@ Install as a dependency with:
|
|
|
287
391
|
npm install @roackb2/heddle
|
|
288
392
|
```
|
|
289
393
|
|
|
394
|
+
For a small real-LLM example of embedding the loop with a custom host tool:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
export OPENAI_API_KEY=your_key_here
|
|
398
|
+
yarn example:programmatic
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
To try the same example with Claude:
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
export ANTHROPIC_API_KEY=your_key_here
|
|
405
|
+
HEDDLE_EXAMPLE_MODEL=claude-3-5-haiku-latest yarn example:programmatic
|
|
406
|
+
```
|
|
407
|
+
|
|
290
408
|
The public API lives in [src/index.ts](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/src/index.ts).
|
|
291
409
|
|
|
292
410
|
## Design Direction
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../examples/heartbeat.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Example: Heartbeat
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// OPENAI_API_KEY=sk-... yarn example:heartbeat
|
|
6
|
+
//
|
|
7
|
+
// Optional:
|
|
8
|
+
// HEDDLE_EXAMPLE_MODEL=claude-3-5-haiku-latest ANTHROPIC_API_KEY=sk-ant-... yarn example:heartbeat
|
|
9
|
+
//
|
|
10
|
+
// This demonstrates one scheduler-style heartbeat wake cycle. It loads a local
|
|
11
|
+
// checkpoint if one exists, wakes the agent without a chat message, lets it work
|
|
12
|
+
// within a small step budget, then persists the next checkpoint.
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { inferProviderFromModel } from '../src/llm/providers.js';
|
|
16
|
+
import { resolveProviderApiKey } from '../src/runtime/api-keys.js';
|
|
17
|
+
import { createFileHeartbeatCheckpointStore, runStoredHeartbeat } from '../src/runtime/heartbeat-store.js';
|
|
18
|
+
const DEFAULT_EXAMPLE_MODEL = 'gpt-5.1-codex-mini';
|
|
19
|
+
const CHECKPOINT_PATH = join(process.cwd(), '.heddle', 'examples', 'heartbeat-demo-checkpoint.json');
|
|
20
|
+
async function main() {
|
|
21
|
+
const model = process.env.HEDDLE_EXAMPLE_MODEL ?? process.env.OPENAI_MODEL ?? DEFAULT_EXAMPLE_MODEL;
|
|
22
|
+
const provider = inferProviderFromModel(model);
|
|
23
|
+
const apiKey = resolveProviderApiKey(provider);
|
|
24
|
+
if (!apiKey) {
|
|
25
|
+
throw new Error(`Missing API key for ${provider}. ` +
|
|
26
|
+
'Set OPENAI_API_KEY for OpenAI models or ANTHROPIC_API_KEY for Claude models before running this example.');
|
|
27
|
+
}
|
|
28
|
+
const store = createFileHeartbeatCheckpointStore({ path: CHECKPOINT_PATH });
|
|
29
|
+
const result = await runStoredHeartbeat({
|
|
30
|
+
store,
|
|
31
|
+
task: 'Check whether there is useful autonomous work to do for this demo. No tools are available in this demo wake cycle. If no external task is available, explain that this wake cycle should pause.',
|
|
32
|
+
model,
|
|
33
|
+
apiKey,
|
|
34
|
+
tools: [],
|
|
35
|
+
includeDefaultTools: false,
|
|
36
|
+
workspaceRoot: process.cwd(),
|
|
37
|
+
onEvent(event) {
|
|
38
|
+
if (event.type === 'loop.started') {
|
|
39
|
+
console.log(`[event] heartbeat.started model=${event.model} provider=${event.provider}`);
|
|
40
|
+
}
|
|
41
|
+
if (event.type === 'trace' && event.event.type === 'tool.call') {
|
|
42
|
+
console.log(`[trace] tool.call step=${event.event.step} tool=${event.event.call.tool}`);
|
|
43
|
+
}
|
|
44
|
+
if (event.type === 'loop.finished') {
|
|
45
|
+
console.log(`[event] heartbeat.finished outcome=${event.outcome} trace=${event.state.trace.length}`);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
console.log('\nHeartbeat result:\n');
|
|
50
|
+
console.log(`loadedCheckpoint=${result.loadedCheckpoint}`);
|
|
51
|
+
console.log(`decision=${result.decision}`);
|
|
52
|
+
console.log(`nextDelayMs=${result.nextDelayMs ?? 'none'}`);
|
|
53
|
+
console.log(`summary=${result.summary}`);
|
|
54
|
+
console.log(`checkpoint=${CHECKPOINT_PATH}`);
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
main().catch((error) => {
|
|
58
|
+
console.error(error);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../examples/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"programmatic-loop.d.ts","sourceRoot":"","sources":["../../examples/programmatic-loop.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Example: Programmatic Loop
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// OPENAI_API_KEY=sk-... yarn example:programmatic
|
|
6
|
+
//
|
|
7
|
+
// Optional:
|
|
8
|
+
// HEDDLE_EXAMPLE_MODEL=claude-3-5-haiku-latest ANTHROPIC_API_KEY=sk-ant-... yarn example:programmatic
|
|
9
|
+
//
|
|
10
|
+
// This example uses a real LLM plus one custom host tool. It demonstrates how
|
|
11
|
+
// another app can embed Heddle as an evented execution loop without going
|
|
12
|
+
// through the terminal chat UI.
|
|
13
|
+
//
|
|
14
|
+
// For a no-key test of this API, see src/__tests__/agent-loop.test.ts.
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
import { runAgentLoop } from '../src/runtime/agent-loop.js';
|
|
17
|
+
import { createAgentLoopCheckpoint } from '../src/runtime/events.js';
|
|
18
|
+
import { resolveProviderApiKey } from '../src/runtime/api-keys.js';
|
|
19
|
+
import { inferProviderFromModel } from '../src/llm/providers.js';
|
|
20
|
+
const DEFAULT_EXAMPLE_MODEL = 'gpt-5.1-codex-mini';
|
|
21
|
+
const echoTool = {
|
|
22
|
+
name: 'echo_context',
|
|
23
|
+
description: 'Echoes a small piece of host-provided context.',
|
|
24
|
+
parameters: {
|
|
25
|
+
type: 'object',
|
|
26
|
+
properties: {
|
|
27
|
+
topic: { type: 'string' },
|
|
28
|
+
},
|
|
29
|
+
required: ['topic'],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
async execute(input) {
|
|
33
|
+
return {
|
|
34
|
+
ok: true,
|
|
35
|
+
output: {
|
|
36
|
+
input,
|
|
37
|
+
note: 'This result came from a custom host tool.',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
async function main() {
|
|
43
|
+
const model = process.env.HEDDLE_EXAMPLE_MODEL ?? process.env.OPENAI_MODEL ?? DEFAULT_EXAMPLE_MODEL;
|
|
44
|
+
const provider = inferProviderFromModel(model);
|
|
45
|
+
const apiKey = resolveProviderApiKey(provider);
|
|
46
|
+
if (!apiKey) {
|
|
47
|
+
throw new Error(`Missing API key for ${provider}. ` +
|
|
48
|
+
'Set OPENAI_API_KEY for OpenAI models or ANTHROPIC_API_KEY for Claude models before running this example.');
|
|
49
|
+
}
|
|
50
|
+
const result = await runAgentLoop({
|
|
51
|
+
goal: 'Use the echo_context tool once, then explain in two short sentences how another app can embed Heddle as a programmatic agent loop.',
|
|
52
|
+
model,
|
|
53
|
+
apiKey,
|
|
54
|
+
tools: [echoTool],
|
|
55
|
+
includeDefaultTools: false,
|
|
56
|
+
maxSteps: 3,
|
|
57
|
+
onEvent(event) {
|
|
58
|
+
const line = formatExampleEvent(event);
|
|
59
|
+
if (line) {
|
|
60
|
+
console.log(line);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
console.log('\nFinal answer:\n');
|
|
65
|
+
console.log(result.summary);
|
|
66
|
+
const checkpoint = createAgentLoopCheckpoint(result.state);
|
|
67
|
+
console.log('\nCheckpoint preview:\n');
|
|
68
|
+
console.log(JSON.stringify({
|
|
69
|
+
version: checkpoint.version,
|
|
70
|
+
model: checkpoint.state.model,
|
|
71
|
+
outcome: checkpoint.state.outcome,
|
|
72
|
+
transcriptMessages: checkpoint.state.transcript.length,
|
|
73
|
+
traceEvents: checkpoint.state.trace.length,
|
|
74
|
+
}, null, 2));
|
|
75
|
+
process.exit(0);
|
|
76
|
+
}
|
|
77
|
+
function formatExampleEvent(event) {
|
|
78
|
+
switch (event.type) {
|
|
79
|
+
case 'loop.started':
|
|
80
|
+
return `[event] loop.started model=${event.model} provider=${event.provider} workspace=${event.workspaceRoot}`;
|
|
81
|
+
case 'assistant.stream':
|
|
82
|
+
return event.done ? `[event] assistant.stream.done chars=${event.text.length} step=${event.step}` : undefined;
|
|
83
|
+
case 'loop.finished':
|
|
84
|
+
return `[event] loop.finished outcome=${event.outcome} transcript=${event.state.transcript.length} trace=${event.state.trace.length} input=${event.usage?.inputTokens ?? 0} output=${event.usage?.outputTokens ?? 0} total=${event.usage?.totalTokens ?? 0}`;
|
|
85
|
+
case 'trace':
|
|
86
|
+
return formatTraceEvent(event.event);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function formatTraceEvent(event) {
|
|
90
|
+
switch (event.type) {
|
|
91
|
+
case 'run.started':
|
|
92
|
+
return `[trace] run.started goal=${JSON.stringify(shorten(event.goal))}`;
|
|
93
|
+
case 'assistant.turn':
|
|
94
|
+
return `[trace] assistant.turn step=${event.step} tools=${event.requestedTools ? event.toolCalls?.map((call) => call.tool).join(',') || 'yes' : 'none'} content=${JSON.stringify(shorten(event.content))}`;
|
|
95
|
+
case 'tool.approval_requested':
|
|
96
|
+
return `[trace] tool.approval_requested step=${event.step} tool=${event.call.tool}`;
|
|
97
|
+
case 'tool.approval_resolved':
|
|
98
|
+
return `[trace] tool.approval_resolved step=${event.step} tool=${event.call.tool} approved=${event.approved}`;
|
|
99
|
+
case 'tool.fallback':
|
|
100
|
+
return `[trace] tool.fallback step=${event.step} from=${event.fromCall.tool} to=${event.toCall.tool} reason=${JSON.stringify(shorten(event.reason))}`;
|
|
101
|
+
case 'tool.call':
|
|
102
|
+
return `[trace] tool.call step=${event.step} tool=${event.call.tool} input=${JSON.stringify(event.call.input)}`;
|
|
103
|
+
case 'tool.result':
|
|
104
|
+
return `[trace] tool.result step=${event.step} tool=${event.tool} ok=${event.result.ok} output=${JSON.stringify(formatUnknown(event.result.output ?? event.result.error ?? ''))}`;
|
|
105
|
+
case 'run.finished':
|
|
106
|
+
return `[trace] run.finished step=${event.step} outcome=${event.outcome} summary=${JSON.stringify(shorten(event.summary))}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function shorten(value, maxLength = 96) {
|
|
110
|
+
const normalized = value.replace(/\s+/g, ' ').trim();
|
|
111
|
+
if (normalized.length <= maxLength) {
|
|
112
|
+
return normalized;
|
|
113
|
+
}
|
|
114
|
+
return `${normalized.slice(0, maxLength - 1)}…`;
|
|
115
|
+
}
|
|
116
|
+
function formatUnknown(value) {
|
|
117
|
+
if (typeof value === 'string') {
|
|
118
|
+
return shorten(value);
|
|
119
|
+
}
|
|
120
|
+
return shorten(JSON.stringify(value));
|
|
121
|
+
}
|
|
122
|
+
main().catch((error) => {
|
|
123
|
+
console.error(error);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=programmatic-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"programmatic-loop.js","sourceRoot":"","sources":["../../examples/programmatic-loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../../src/cli/ask.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../../src/cli/ask.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,iBAiCxE"}
|
package/dist/src/cli/ask.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { DEFAULT_OPENAI_MODEL,
|
|
3
|
+
import { DEFAULT_OPENAI_MODEL, inferProviderFromModel, runAgentLoop, formatTraceForConsole, createLogger, resolveProviderApiKey, } from '../index.js';
|
|
4
4
|
export async function runAskCli(goal, options = {}) {
|
|
5
5
|
if (!goal.trim()) {
|
|
6
6
|
throw new Error('Usage: heddle ask "<goal>"');
|
|
@@ -12,36 +12,18 @@ export async function runAskCli(goal, options = {}) {
|
|
|
12
12
|
const logger = createLogger({ pretty: true, level: 'debug' });
|
|
13
13
|
const provider = inferProviderFromModel(model);
|
|
14
14
|
logger.info({ goal, model, provider, maxSteps, cwd: workspaceRoot }, 'Heddle');
|
|
15
|
-
const
|
|
15
|
+
const result = await runAgentLoop({
|
|
16
|
+
goal,
|
|
16
17
|
model,
|
|
17
18
|
apiKey: options.apiKey ?? resolveProviderApiKey(provider),
|
|
19
|
+
maxSteps,
|
|
20
|
+
logger,
|
|
21
|
+
workspaceRoot,
|
|
22
|
+
stateDir: options.stateDir,
|
|
23
|
+
searchIgnoreDirs: options.searchIgnoreDirs,
|
|
24
|
+
systemContext: options.systemContext,
|
|
25
|
+
includePlanTool: false,
|
|
18
26
|
});
|
|
19
|
-
const webSearchTool = createWebSearchTool({
|
|
20
|
-
model,
|
|
21
|
-
provider,
|
|
22
|
-
apiKey: options.apiKey ?? resolveProviderApiKey(provider),
|
|
23
|
-
});
|
|
24
|
-
const viewImageTool = createViewImageTool({
|
|
25
|
-
model,
|
|
26
|
-
provider,
|
|
27
|
-
apiKey: options.apiKey ?? resolveProviderApiKey(provider),
|
|
28
|
-
});
|
|
29
|
-
const tools = [
|
|
30
|
-
listFilesTool,
|
|
31
|
-
readFileTool,
|
|
32
|
-
editFileTool,
|
|
33
|
-
createSearchFilesTool({ excludedDirs: options.searchIgnoreDirs }),
|
|
34
|
-
webSearchTool,
|
|
35
|
-
viewImageTool,
|
|
36
|
-
createListMemoryNotesTool({ memoryRoot: join(stateRoot, 'memory') }),
|
|
37
|
-
createReadMemoryNoteTool({ memoryRoot: join(stateRoot, 'memory') }),
|
|
38
|
-
createSearchMemoryNotesTool({ memoryRoot: join(stateRoot, 'memory') }),
|
|
39
|
-
createEditMemoryNoteTool({ memoryRoot: join(stateRoot, 'memory') }),
|
|
40
|
-
reportStateTool,
|
|
41
|
-
createRunShellInspectTool(),
|
|
42
|
-
createRunShellMutateTool(),
|
|
43
|
-
];
|
|
44
|
-
const result = await runAgent({ goal, llm, tools, maxSteps, logger, systemContext: options.systemContext });
|
|
45
27
|
process.stdout.write(`${formatTraceForConsole(result.trace)}\n`);
|
|
46
28
|
const traceDir = join(stateRoot, 'traces');
|
|
47
29
|
mkdirSync(traceDir, { recursive: true });
|
|
@@ -59,17 +41,4 @@ function parsePositiveInt(raw) {
|
|
|
59
41
|
}
|
|
60
42
|
return value;
|
|
61
43
|
}
|
|
62
|
-
function resolveProviderApiKey(provider) {
|
|
63
|
-
switch (provider) {
|
|
64
|
-
case 'openai':
|
|
65
|
-
return firstDefinedNonEmpty(process.env.OPENAI_API_KEY, process.env.PERSONAL_OPENAI_API_KEY);
|
|
66
|
-
case 'anthropic':
|
|
67
|
-
return firstDefinedNonEmpty(process.env.ANTHROPIC_API_KEY, process.env.PERSONAL_ANTHROPIC_API_KEY);
|
|
68
|
-
case 'google':
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
function firstDefinedNonEmpty(...values) {
|
|
73
|
-
return values.find((value) => typeof value === 'string' && value.trim().length > 0);
|
|
74
|
-
}
|
|
75
44
|
//# sourceMappingURL=ask.js.map
|
package/dist/src/cli/ask.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/cli/ask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/cli/ask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,YAAY,EACZ,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAYrB,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,UAAyB,EAAE;IACvE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,oBAAoB,CAAC;IAC/G,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAC1F,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAE/C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,EAAE,QAAQ,CAAC,CAAC;IAE/E,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,IAAI;QACJ,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,qBAAqB,CAAC,QAAQ,CAAC;QACzD,QAAQ;QACR,MAAM;QACN,aAAa;QACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;QAC1C,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,eAAe,EAAE,KAAK;KACvB,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjE,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC3C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC7D,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAuB;IAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAgentRun.d.ts","sourceRoot":"","sources":["../../../../../src/cli/chat/hooks/useAgentRun.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAc,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"useAgentRun.d.ts","sourceRoot":"","sources":["../../../../../src/cli/chat/hooks/useAgentRun.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import { createLogger, createLlmAdapter,
|
|
2
|
+
import { createLogger, createLlmAdapter, createDefaultAgentTools, runAgentLoop, } from '../../../index.js';
|
|
3
3
|
import { DEFAULT_INSPECT_RULES, DEFAULT_MUTATE_RULES, runShellCommand } from '../../../tools/run-shell.js';
|
|
4
4
|
import { previewEditFileInput } from '../../../tools/edit-file.js';
|
|
5
5
|
import { appendDirectShellHistory, buildConversationMessages, countAssistantSteps, formatChatFailureMessage, formatEditPreviewHistoryMessage, formatPlanHistoryMessage, formatDirectShellResponse, shouldFallbackToMutate, summarizeTrace, summarizeToolCall, toLiveEvent, } from '../utils/format.js';
|
|
@@ -19,31 +19,15 @@ export function useAgentRun(args) {
|
|
|
19
19
|
const llm = useMemo(() => createLlmAdapter({ model: activeModel, apiKey: activeApiKey }), [activeApiKey, activeModel]);
|
|
20
20
|
const titleLlm = useMemo(() => createLlmAdapter({ model: sessionTitleModel, apiKey: titleApiKey }), [sessionTitleModel, titleApiKey]);
|
|
21
21
|
const tools = useMemo(() => {
|
|
22
|
-
|
|
22
|
+
return createDefaultAgentTools({
|
|
23
23
|
model: activeModel,
|
|
24
24
|
apiKey: activeApiKey,
|
|
25
|
+
workspaceRoot: runtime.workspaceRoot,
|
|
26
|
+
memoryDir: runtime.memoryDir,
|
|
27
|
+
searchIgnoreDirs: runtime.searchIgnoreDirs,
|
|
28
|
+
includePlanTool: true,
|
|
25
29
|
});
|
|
26
|
-
|
|
27
|
-
model: activeModel,
|
|
28
|
-
apiKey: activeApiKey,
|
|
29
|
-
});
|
|
30
|
-
return [
|
|
31
|
-
listFilesTool,
|
|
32
|
-
readFileTool,
|
|
33
|
-
editFileTool,
|
|
34
|
-
createSearchFilesTool({ excludedDirs: runtime.searchIgnoreDirs }),
|
|
35
|
-
webSearchTool,
|
|
36
|
-
viewImageTool,
|
|
37
|
-
createListMemoryNotesTool({ memoryRoot: runtime.memoryDir }),
|
|
38
|
-
createReadMemoryNoteTool({ memoryRoot: runtime.memoryDir }),
|
|
39
|
-
createSearchMemoryNotesTool({ memoryRoot: runtime.memoryDir }),
|
|
40
|
-
createEditMemoryNoteTool({ memoryRoot: runtime.memoryDir }),
|
|
41
|
-
reportStateTool,
|
|
42
|
-
updatePlanTool,
|
|
43
|
-
createRunShellInspectTool(),
|
|
44
|
-
createRunShellMutateTool(),
|
|
45
|
-
];
|
|
46
|
-
}, [activeApiKey, activeModel, runtime.searchIgnoreDirs]);
|
|
30
|
+
}, [activeApiKey, activeModel, runtime.memoryDir, runtime.searchIgnoreDirs, runtime.workspaceRoot]);
|
|
47
31
|
const logger = useMemo(() => createLogger({
|
|
48
32
|
pretty: false,
|
|
49
33
|
level: 'debug',
|
|
@@ -147,10 +131,15 @@ export async function executeAgentTurn(args) {
|
|
|
147
131
|
}));
|
|
148
132
|
}
|
|
149
133
|
try {
|
|
150
|
-
const result = await
|
|
134
|
+
const result = await runAgentLoop({
|
|
151
135
|
goal: prompt,
|
|
136
|
+
model: llm.info?.model ?? runtime.model,
|
|
137
|
+
workspaceRoot: runtime.workspaceRoot,
|
|
138
|
+
memoryDir: runtime.memoryDir,
|
|
139
|
+
searchIgnoreDirs: runtime.searchIgnoreDirs,
|
|
152
140
|
llm,
|
|
153
141
|
tools,
|
|
142
|
+
includeDefaultTools: false,
|
|
154
143
|
maxSteps: runtime.maxSteps,
|
|
155
144
|
logger,
|
|
156
145
|
history: sessionHistory,
|
|
@@ -162,7 +151,7 @@ export async function executeAgentTurn(args) {
|
|
|
162
151
|
streamingBuffers.delete(update.step);
|
|
163
152
|
}
|
|
164
153
|
},
|
|
165
|
-
|
|
154
|
+
onTraceEvent: (event) => {
|
|
166
155
|
if (event.type === 'assistant.turn' && event.content.trim() && !appendedAssistantSteps.has(event.step)) {
|
|
167
156
|
appendedAssistantSteps.add(event.step);
|
|
168
157
|
streamingBuffers.delete(event.step);
|