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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `createAgent()` agents can pause for approval (LOU-D21): a `needsApproval` tool no longer fails the run with "requires approval but no approvalStore". The run pauses (`finishReason: 'awaiting-approval'`) in a per-agent `InMemoryApprovalStore` (or the new `approvalStore` option), and `agent.approvals.list()` / `agent.approvals.resolve({ id, approved, note? })` continue it, in its session if it paused in one. The `approve` option decides calls in code without pausing.
- Tools own their contract (LOU-D22): `ToolDescriptor` gains optional `inputSchema` (zod) and `execute(args, ctx)`, which are now the canonical fields. `defineTool()` sets both and no longer calls `ai`'s `tool()`. Argument validation, the schema sent to the model, and tool execution read them first and fall back to `tool.parameters` / `tool.execute`. `ToolDescriptor.tool` (the `ai` v4 `Tool`) is now legacy: it is still built by `defineTool()` and still accepted on hand-written descriptors this release, but new code should set `inputSchema` and `execute`.

### Removed
- BREAKING: The flows-ai converters (LOU-D35) are gone: `convertToFlowDefinition()` and `convertFromFlowDefinition()` (`src/flows/converters.ts`) no longer ship from the package root or `./flows`. There is no replacement: the flows-ai engine they targeted was never a dependency of this package and `FlowExecutor` never used them. Run flows with `FlowExecutor` directly.
- `nanoid` is no longer a dependency (LOU-D35). Generated ids (agent, run, trace, memory ids) now come from `globalThis.crypto.randomUUID()` via an internal `newId()`, so they are UUIDs instead of 21-character nanoids. Nothing public depended on the old format.
- `finishReason: 'max-steps'` (LOU-U19): a run that exhausts `maxSteps` while the model still wanted to continue (last turn ended in tool calls) now resolves with `finishReason: 'max-steps'` instead of the stale last-turn reason (usually `'tool_calls'`), on `ExecutionResult`, the `finish` event and `run.done`. Resumed runs count `initialSteps` toward the budget. A run that finishes naturally within the budget is unchanged. Code that treated `'tool_calls'` as "hit maxSteps" should check `'max-steps'` instead (the eval `completed()` message and the MCP server's agent tool do).

### Docs
Expand Down
19 changes: 0 additions & 19 deletions package-lock.json

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

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@
"dependencies": {
"@modelcontextprotocol/sdk": "^1.30.1",
"dockerode": "^5.0.1",
"nanoid": "^5.0.7",
"prompts": "^2.4.2",
"undici": "^8.11.2",
"yaml": "^2.9.1"
Expand Down
4 changes: 2 additions & 2 deletions src/core/AgentBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AgentConfig, AgentType, ToolConfiguration, AgentFlow } from '../types';
import { validateAgentConfig, validateAgentTools } from '../agent-types';
import { nanoid } from 'nanoid';
import { newId } from '../utils/id';
import type { DefinedTool } from '../tools/defineTool';

/**
Expand Down Expand Up @@ -109,7 +109,7 @@
/**
* Set expected result schema
*/
public setExpectedResult(schema: any): this {

Check warning on line 112 in src/core/AgentBuilder.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected any. Specify a different type
this.config.expectedResult = schema;
return this;
}
Expand All @@ -125,7 +125,7 @@
/**
* Set events
*/
public setEvents(events: any[]): this {

Check warning on line 128 in src/core/AgentBuilder.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected any. Specify a different type
this.config.events = events;
return this;
}
Expand All @@ -133,7 +133,7 @@
/**
* Set settings
*/
public setSettings(settings: Record<string, any>): this {

Check warning on line 136 in src/core/AgentBuilder.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected any. Specify a different type
this.config.settings = settings;
return this;
}
Expand All @@ -141,7 +141,7 @@
/**
* Set metadata
*/
public setMetadata(metadata: Record<string, any>): this {

Check warning on line 144 in src/core/AgentBuilder.ts

View workflow job for this annotation

GitHub Actions / ci

Unexpected any. Specify a different type
this.config.metadata = metadata;
return this;
}
Expand All @@ -153,7 +153,7 @@
this.validate();

return {
id: this.config.id || nanoid(),
id: this.config.id || newId(),
name: this.config.name!,
...(this.config.agentType !== undefined && { agentType: this.config.agentType }),
locale: this.config.locale || 'en',
Expand Down
10 changes: 5 additions & 5 deletions src/data/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
PaginatedResult,
} from './repositories';
import { Agent, Session, Result, Memory, Attachment } from './models';
import { nanoid } from 'nanoid';
import { newId } from '../utils/id';

/**
* Base Mock Repository
Expand Down Expand Up @@ -89,7 +89,7 @@ export class MockAgentRepository
implements AgentRepository
{
protected generateId(): string {
return nanoid();
return newId();
}

async findByType(type: string): Promise<Agent[]> {
Expand Down Expand Up @@ -138,7 +138,7 @@ export class MockSessionRepository
implements SessionRepository
{
protected generateId(): string {
return nanoid();
return newId();
}

async findByAgentId(agentId: string): Promise<Session[]> {
Expand Down Expand Up @@ -183,7 +183,7 @@ export class MockResultRepository
implements ResultRepository
{
protected generateId(): string {
return nanoid();
return newId();
}

async findBySessionId(sessionId: string): Promise<Result | null> {
Expand Down Expand Up @@ -214,7 +214,7 @@ export class MockMemoryRepository
implements MemoryRepository
{
protected generateId(): string {
return nanoid();
return newId();
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/execution/AgentExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Skill } from '../skills/defineSkill';
import { withSkills } from '../skills/withSkills';
import type { Subagents } from '../subagents/types';
import { assertMaxSubagentDepth, withSubagents } from '../subagents/withSubagents';
import { nanoid } from 'nanoid';
import { newId } from '../utils/id';
import { LLMProvider, Message, ToolCall, GenerateOptions, GenerateResult, ToolDefinition } from '../providers';
import { AgentConfig } from '../types';
import { ToolRegistry } from '../tools';
Expand Down Expand Up @@ -1033,7 +1033,7 @@ export class AgentExecutor {
}

const pending: PendingApproval = {
id: nanoid(),
id: newId(),
toolCallId: toolCall.id,
toolName: toolCall.function.name,
args: toolResult.args || {},
Expand Down
4 changes: 2 additions & 2 deletions src/execution/MemoryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { Memory, MemoryRepository } from '../data';
import { nanoid } from 'nanoid';
import { newId } from '../utils/id';

/**
* Memory manager configuration
Expand Down Expand Up @@ -124,7 +124,7 @@ export class MemoryManager {
};

const memory = new Memory({
id: nanoid(),
id: newId(),
agentId,
content,
embedding: embedding ?? [],
Expand Down
4 changes: 2 additions & 2 deletions src/execution/agentRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* buffered without loss until they are read.
*/

import { nanoid } from 'nanoid';
import { newId } from '../utils/id';
import type { GenerateOptions, GenerateResult, LLMProvider } from '../providers';
import type { ExecuteOptions, ExecutionEvent, ExecutionResult } from './AgentExecutor';
import type { PendingApproval } from './ApprovalGate';
Expand Down Expand Up @@ -140,7 +140,7 @@ function toJsonValue(value: unknown): unknown {
type MeasuredStep = { finishReason: GenerateResult['finishReason']; usage: Usage; estimated: boolean; costUsd?: number };

class AgentRunImpl implements AgentRun {
readonly runId = nanoid();
readonly runId = newId();
readonly result: Promise<ExecutionResult>;
private readonly controller = new AbortController();
private readonly queue: AgentEvent[] = [];
Expand Down
4 changes: 2 additions & 2 deletions src/execution/tracing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* for a console bridge and a real OTel bridge.
*/

import { nanoid } from 'nanoid';
import { newId } from '../utils/id';
import { ErrorAttr, LegacyAttr } from './semconv';

/** OpenTelemetry span kind, for the kinds this SDK emits. */
Expand Down Expand Up @@ -90,7 +90,7 @@ export async function withSpan<T>(
kind?: SpanKind
): Promise<T> {
const span: Span = {
id: nanoid(),
id: newId(),
name,
attributes,
startTime: Date.now(),
Expand Down
4 changes: 2 additions & 2 deletions src/flows/FlowBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { nanoid } from 'nanoid';
import { newId } from '../utils/id';
import { EditorStep, AgentFlow, FlowInputVariable } from '../types';

/** Throw on the first input variable with a missing or duplicate name. */
Expand Down Expand Up @@ -107,7 +107,7 @@ export class FlowBuilder {
this.validate();

return {
id: this.flow.id || nanoid(),
id: this.flow.id || newId(),
code: this.flow.code!,
name: this.flow.name!,
description: this.flow.description,
Expand Down
Loading
Loading