Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Use dreb if you want a coding agent that can run against direct APIs, coding sub
- **Model and provider freedom.** Authenticate with API keys or `/login` subscriptions, switch models at runtime with `/model`, scope model sets, tune thinking levels, route built-in providers through proxies, use cloud providers such as Bedrock/Vertex/Azure, or add local/proxy/custom models through [Custom Models](packages/coding-agent/docs/models.md) and [Custom Providers](packages/coding-agent/docs/custom-provider.md). See [Providers](packages/coding-agent/docs/providers.md) for the current setup list.
- **A real development workflow.** [mach6](packages/coding-agent/docs/mach6.md) is a built-in issue-to-merge workflow: assess issues, plan work, open draft PRs, implement, push progress, run multi-agent reviews, independently assess findings, fix CI or review items, and publish. Plans, reviews, and progress live on GitHub as shared memory.
- **Composable agent building blocks.** [Skills](packages/coding-agent/docs/skills.md) are markdown workflows loaded on demand; [extensions](packages/coding-agent/docs/extensions.md) are TypeScript modules for custom tools, commands, event hooks, UI components, renderers, keybindings, provider registration, permission gates, and workflow automation; [packages](packages/coding-agent/docs/packages.md) bundle skills, extensions, prompts, and themes for npm, git, or local sharing.
- **Parallel and specialized agents.** The `subagent` tool runs independent child agents in single, parallel, or chain mode. Custom agent definitions can inherit models, record child-session metadata for audit trails, and power workflows such as mach6's specialized code, error, test, completeness, and simplification reviewers. Per-agent models can be overridden via the [`agentModels` setting](packages/coding-agent/docs/agent-models.md) without editing agent definition files. The parent session's running model is exposed in its own system prompt (`You are running on: provider/id`), enabling self-aware routing decisions such as delegating to a multimodal or differently-architected subagent. While background subagents run, a guardrail pauses the parent after a few turns and surfaces a friendly, non-error notification (in the TUI and Telegram) explaining the intentional pause — configurable or disable-able via [`backgroundAgents`](packages/coding-agent/docs/settings.md#background-agents).
- **Parallel and specialized agents.** The `subagent` tool runs independent child agents in single, parallel, or chain mode. Custom agent definitions can inherit models, record child-session metadata for audit trails, and power workflows such as mach6's specialized reviewers. Per-agent models and per-request thinking remain explicit controls. The built-in [`model-routing-guide` skill](packages/coding-agent/docs/skills.md#model-routing-guide) researches scoped provider/model candidates and local child history, and its `update` mode preserves retained entries while removing stale scope and researching newly added models; the optional global-only [Dispatch Arbiter](packages/coding-agent/docs/agent-models.md#dispatch-arbiter) consumes that guide in a fully headless, tool-less call before every child spawn and may change only agent, scoped canonical model, and supported thinking. Its bounded rolling parent activity follows the title setter and includes useful tool outputs, with existing secret scrubbing applied before inference. It is disabled by default and fails closed—bad configuration, guide, inference, or decisions prevent the child from spawning rather than silently keeping the original route. TUI `/settings` and dashboard Settings expose its enable toggle, exact model, thinking, guide path, and validation/readiness feedback. Typed decisions are persisted and visible in the TUI, JSON/RPC, and dashboard. While background subagents run, a separate guardrail pauses the parent after a few turns, configurable via [`backgroundAgents`](packages/coding-agent/docs/settings.md#background-agents).
- **Durable context.** [Sessions](packages/coding-agent/docs/session.md) are JSONL trees with resume/continue, `/tree` navigation, `/fork`, CLI `--fork`, compaction, HTML export, and JSONL import/export. [Memory](packages/coding-agent/README.md#memory) is file-based, global + project-scoped, survives sessions, can read Claude Code project memory, and can be maintained with `/dream` memory consolidation.
- **A capable terminal workspace.** The TUI supports slash commands, file references with `@`, path completion, image paste/drag, bash shortcuts, hotkeys, settings, model cycling, steering/follow-up queues while the agent is working, token/cost/context status, custom themes, and extension-provided UI surfaces. Transcript prose, code, tool output, and agent results use terminal soft-wrap so copying from scrollback keeps long logical lines intact instead of injecting hard newlines.
- **Optional local companion.** [`/buddy`](packages/coding-agent/docs/buddy.md) hatches an Ollama-powered terminal companion with persistent state, generated personality/backstory, event reactions, idle quips, name-call responses, pet/reroll/stats commands, and a sidebar presence while you work.
Expand Down Expand Up @@ -135,7 +135,7 @@ The dashboard is the visual face of dreb: every agent session on the host, live

<!-- screenshot: session view with tool cards + subagent strip, desktop (dark) -->

**Live subagent observability.** Background subagents are first-class: chips on the parent session, live counts on fleet cards, and a read-only drill-in transcript per agent that streams in real time and survives browser reloads.
**Live subagent observability.** Background subagents are first-class: chips on the parent session, live counts on fleet cards, and a read-only drill-in transcript per agent that streams in real time and survives browser reloads. When the Dispatch Arbiter is enabled, those views also show its host-validated changed, unchanged, or failed pre-spawn decision and the final routed agent/model/thinking—never raw arbiter output.

**Live connection recovery.** The top bar and persistent session header have an accessible, text-labelled connection indicator (connecting, connected, retrying, resyncing, disconnected, or auth failed). SSE uses bounded replay and an authoritative snapshot barrier to recover from browser reloads, server restarts, sequence gaps, slow-client backpressure, and stalls without duplicating state; task lists restore with the session snapshot. Named 25-second heartbeats and a foreground 60-second liveness watchdog detect a stuck stream. See [dashboard recovery details](packages/coding-agent/docs/dashboard.md#live-connection-and-recovery) and the [RPC ordering contract](packages/coding-agent/docs/rpc.md#get_dashboard_snapshot).

Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"node": "22.x"
},
"packageManager": "npm@11.5.1",
"version": "2.45.4",
"version": "2.46.0",
"dependencies": {
"@dreb/coding-agent": "*",
"@mariozechner/jiti": "^2.6.5",
Expand Down
8 changes: 7 additions & 1 deletion packages/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ The last message in context must be `user` or `toolResult` (not `assistant`).

| Event | Description |
|-------|-------------|
| `agent_start` | Agent begins processing |
| `agent_start` | Agent begins processing; includes resolved model and effective thinking level |
| `agent_end` | Agent completes with all new messages |
| `turn_start` | New turn begins (one LLM call + tool executions) |
| `turn_end` | Turn completes with assistant message and tool results |
Expand All @@ -136,6 +136,12 @@ The last message in context must be `user` or `toolResult` (not `assistant`).
| `tool_execution_update` | Tool streams progress |
| `tool_execution_end` | Tool completes |

`agent_start` carries the provider/model identity and the effective thinking level sent to the provider for that run:

```typescript
{ type: "agent_start", model: { provider: "anthropic", id: "claude-sonnet-4-6" }, thinkingLevel: "high" }
```

## Agent Options

```typescript
Expand Down
2 changes: 1 addition & 1 deletion packages/agent/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dreb/agent-core",
"version": "2.45.4",
"version": "2.46.0",
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
"type": "module",
"main": "./dist/index.js",
Expand Down
20 changes: 18 additions & 2 deletions packages/agent/src/agent-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DEFAULT_MAX_OUTPUT_TOKENS,
EventStream,
streamSimple,
supportsXhigh,
type ToolResultMessage,
validateToolArguments,
} from "@dreb/ai";
Expand All @@ -21,10 +22,17 @@ import type {
AgentToolCall,
AgentToolResult,
StreamFn,
ThinkingLevel,
} from "./types.js";

export type AgentEventSink = (event: AgentEvent) => Promise<void> | void;

function getEffectiveThinkingLevel(config: AgentLoopConfig): ThinkingLevel {
const requested = config.reasoning ?? "off";
if (!config.model.reasoning) return "off";
return requested === "xhigh" && !supportsXhigh(config.model) ? "high" : requested;
}

/**
* Start an agent loop with a new prompt message.
* The prompt is added to the context and events are emitted for it.
Expand Down Expand Up @@ -107,7 +115,11 @@ export async function runAgentLoop(
messages: [...context.messages, ...prompts],
};

await emit({ type: "agent_start", model: { provider: config.model.provider, id: config.model.id } });
await emit({
type: "agent_start",
model: { provider: config.model.provider, id: config.model.id },
thinkingLevel: getEffectiveThinkingLevel(config),
});
await emit({ type: "turn_start" });
for (const prompt of prompts) {
await emit({ type: "message_start", message: prompt });
Expand Down Expand Up @@ -136,7 +148,11 @@ export async function runAgentLoopContinue(
const newMessages: AgentMessage[] = [];
const currentContext: AgentContext = { ...context };

await emit({ type: "agent_start", model: { provider: config.model.provider, id: config.model.id } });
await emit({
type: "agent_start",
model: { provider: config.model.provider, id: config.model.id },
thinkingLevel: getEffectiveThinkingLevel(config),
});
await emit({ type: "turn_start" });

await runLoop(currentContext, newMessages, config, signal, emit, streamFn);
Expand Down
7 changes: 6 additions & 1 deletion packages/agent/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,12 @@ export interface AgentContext {
*/
export type AgentEvent =
// Agent lifecycle
| { type: "agent_start"; model?: { provider: string; id: string } }
| {
type: "agent_start";
model?: { provider: string; id: string };
/** Effective thinking level sent to the provider for this run. */
thinkingLevel?: ThinkingLevel;
}
| { type: "agent_end"; messages: AgentMessage[] }
// Turn lifecycle - a turn is one assistant response + any tool calls/results
| { type: "turn_start" }
Expand Down
Loading
Loading