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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Use dreb if you want a coding agent that can run against direct APIs, coding sub
## Why choose dreb?

- **Every session, on every device.** The [web dashboard](#web-dashboard) is a first-party browser UI for the same sessions the terminal runs: a fleet overview of all live and past sessions across projects, full chat with steering, live subagent observability, host file access, dreb memory management, and settings — one synchronized state on desktop and mobile. Local-only by default; remote access is Tailscale-gated with device pairing.
- **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.
- **Model and provider freedom.** Authenticate with API keys or `/login` subscriptions, switch models at runtime with `/model`, scope model sets, and tune model-aware thinking levels through `xhigh` plus a model-aware `max` tier. Codex `ultra` is orchestration (`max` plus local multi-agent work), not a raw provider effort. 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 optional `subagent` tool runs role-matched work in independent child agents using single, parallel, or chain mode. Omitting the agent type selects `Explore`, which retrieves concrete evidence such as files, symbols, documentation, call sites, exact snippets, and explicit data flows; the primary agent retains root-cause diagnosis, requirements interpretation, design, implementation recommendations, planning, synthesis, and final conclusions. Parallel and chain modes do not relax that boundary, while specialized agents continue to perform the broader work in their own definitions. 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. The same settings surfaces expose `backgroundAgents.maxConcurrentSubagents` (default `4`); `0` starts new parent sessions without the subagent tool and explicitly tells the parent model to perform normally delegated work itself. 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).
Expand Down
131 changes: 100 additions & 31 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.61.0",
"version": "2.61.1",
"dependencies": {
"@dreb/coding-agent": "*",
"@mariozechner/jiti": "^2.6.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const agent = new Agent({
initialState: {
systemPrompt: string,
model: Model<any>,
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh",
thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max",
tools: AgentTool<any>[],
messages: AgentMessage[],
},
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.61.0",
"version": "2.61.1",
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 2 additions & 0 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,
supportsMax,
supportsXhigh,
type ToolResultMessage,
validateToolArguments,
Expand All @@ -30,6 +31,7 @@ export type AgentEventSink = (event: AgentEvent) => Promise<void> | void;
function getEffectiveThinkingLevel(config: AgentLoopConfig): ThinkingLevel {
const requested = config.reasoning ?? "off";
if (!config.model.reasoning) return "off";
if (requested === "max" && !supportsMax(config.model)) return supportsXhigh(config.model) ? "xhigh" : "high";
return requested === "xhigh" && !supportsXhigh(config.model) ? "high" : requested;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/agent/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
* Thinking/reasoning level for models that support it.
* Note: "xhigh" is only supported by OpenAI reasoning models that explicitly advertise extended reasoning (for example GPT-5.2+ and Codex GPT-5.3+).
*/
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh";
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";

/**
* Extensible interface for custom app messages.
Expand Down
3 changes: 2 additions & 1 deletion packages/ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ if (model.reasoning) {
const response = await completeSimple(model, {
messages: [{ role: 'user', content: 'Solve: 2x + 5 = 13' }]
}, {
reasoning: 'medium' // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' (xhigh maps to 'max' on Claude Opus 4.6–4.x and Claude 5 families; 'high' on other Anthropic models)
reasoning: 'medium' // 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
// Native normalized 'max' is model-aware (currently GPT-5.6). Claude's established xhigh mapping still emits provider-native 'max'.
});

// Access thinking and text blocks
Expand Down
4 changes: 2 additions & 2 deletions packages/ai/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dreb/ai",
"version": "2.61.0",
"version": "2.61.1",
"description": "Unified LLM API with automatic model discovery and provider configuration",
"type": "module",
"main": "./dist/index.js",
Expand Down Expand Up @@ -83,7 +83,7 @@
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
"chalk": "^5.6.2",
"openai": "6.26.0",
"openai": "6.49.0",
"partial-json": "^0.1.7",
"proxy-agent": "^6.5.0",
"undici": "^7.19.1",
Expand Down
11 changes: 11 additions & 0 deletions packages/ai/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,17 @@ export function isQwen38OrLater(modelId: string): boolean {
return qwen.major > 3 || (qwen.major === 3 && qwen.minor >= 8);
}

/**
* Check if a model supports the native `max` reasoning tier.
*
* Supported today:
* - GPT-5.6 model families (Sol, Terra, Luna, and the alias)
*/
export function supportsMax<TApi extends Api>(model: Model<TApi>): boolean {
if (/(?:^|\/)gpt-5\.6(?:$|[-.])/.test(model.id.toLowerCase())) return true;
return false;
}

/**
* Check if a model supports xhigh thinking level.
*
Expand Down
6 changes: 4 additions & 2 deletions packages/ai/src/providers/amazon-bedrock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ function mapThinkingLevelToEffort(
case "high":
return "high";
case "xhigh":
case "max":
return supportsXhigh(model) ? "max" : "high";
default:
return "high";
Expand Down Expand Up @@ -732,10 +733,11 @@ export function buildAdditionalModelRequestFields(
medium: 8192,
high: 16384,
xhigh: 16384, // Claude doesn't support xhigh, clamp to high
max: 16384, // Normalized max falls back through xhigh to high here
};

// Custom budgets override defaults (xhigh not in ThinkingBudgets, use high)
const level = options.reasoning === "xhigh" ? "high" : options.reasoning;
// Custom budgets do not define xhigh/max, so both use high.
const level = options.reasoning === "xhigh" || options.reasoning === "max" ? "high" : options.reasoning;
const budget = options.thinkingBudgets?.[level] ?? defaultBudgets[options.reasoning];

return {
Expand Down
1 change: 1 addition & 0 deletions packages/ai/src/providers/anthropic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ function mapThinkingLevelToEffort(
case "high":
return "high";
case "xhigh":
case "max":
return supportsXhigh(model) ? "max" : "high";
default:
return "high";
Expand Down
7 changes: 3 additions & 4 deletions packages/ai/src/providers/azure-openai-responses.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AzureOpenAI } from "openai";
import type { ResponseCreateParamsStreaming } from "openai/resources/responses/responses.js";
import { getEnvApiKey } from "../env-api-keys.js";
import { supportsXhigh } from "../models.js";
import type {
Api,
AssistantMessage,
Expand All @@ -13,7 +12,7 @@ import type {
} from "../types.js";
import { AssistantMessageEventStream } from "../utils/event-stream.js";
import { convertResponsesMessages, convertResponsesTools, processResponsesStream } from "./openai-responses-shared.js";
import { buildBaseOptions, clampReasoning } from "./simple-options.js";
import { buildBaseOptions, resolveReasoningEffort } from "./simple-options.js";

const DEFAULT_AZURE_API_VERSION = "v1";
const AZURE_TOOL_CALL_PROVIDERS = new Set(["openai", "openai-codex", "opencode", "azure-openai-responses"]);
Expand Down Expand Up @@ -41,7 +40,7 @@ function resolveDeploymentName(model: Model<"azure-openai-responses">, options?:

// Azure OpenAI Responses-specific options
export interface AzureOpenAIResponsesOptions extends StreamOptions {
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh";
reasoningEffort?: "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
reasoningSummary?: "auto" | "detailed" | "concise" | null;
azureApiVersion?: string;
azureResourceName?: string;
Expand Down Expand Up @@ -133,7 +132,7 @@ export const streamSimpleAzureOpenAIResponses: StreamFunction<"azure-openai-resp
}

const base = buildBaseOptions(model, options, apiKey);
const reasoningEffort = supportsXhigh(model) ? options?.reasoning : clampReasoning(options?.reasoning);
const reasoningEffort = resolveReasoningEffort(model, options?.reasoning);

return streamAzureOpenAIResponses(model, context, {
...base,
Expand Down
2 changes: 1 addition & 1 deletion packages/ai/src/providers/google-gemini-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ export function buildRequest(
};
}

type ClampedThinkingLevel = Exclude<ThinkingLevel, "xhigh">;
type ClampedThinkingLevel = Exclude<ThinkingLevel, "xhigh" | "max">;

function getDisabledThinkingConfig(modelId: string): ThinkingConfig {
// Google docs: Gemini 3.1 Pro cannot disable thinking, and Gemini 3 Flash / Flash-Lite
Expand Down
Loading
Loading