deepagentsdk 0.10.0 → 0.11.1
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/package.json +11 -5
- package/src/adapters/elements/index.ts +27 -0
- package/src/adapters/elements/messageAdapter.ts +165 -0
- package/src/adapters/elements/statusAdapter.ts +39 -0
- package/src/adapters/elements/types.ts +97 -0
- package/src/adapters/elements/useElementsAdapter.ts +261 -0
- package/src/agent.ts +34 -6
- package/src/backends/persistent.ts +3 -3
- package/src/cli/components/ApiKeyInput.tsx +1 -1
- package/src/cli/components/FilePreview.tsx +2 -2
- package/src/cli/components/Input.tsx +2 -2
- package/src/cli/components/Message.tsx +2 -2
- package/src/cli/components/ModelSelection.tsx +2 -2
- package/src/cli/components/SlashMenu.tsx +1 -1
- package/src/cli/components/StatusBar.tsx +1 -1
- package/src/cli/components/Subagent.tsx +1 -1
- package/src/cli/components/TodoList.tsx +2 -2
- package/src/cli/components/ToolCall.tsx +1 -1
- package/src/cli/components/ToolCallSummary.tsx +2 -2
- package/src/cli/components/Welcome.tsx +1 -1
- package/src/cli/components/index.ts +13 -13
- package/src/cli/hooks/index.ts +1 -1
- package/src/cli/hooks/useAgent.ts +6 -6
- package/src/cli/index.tsx +7 -7
- package/src/middleware/agent-memory.ts +1 -1
- package/src/skills/load.ts +1 -1
- package/src/types/backend.ts +1 -1
- package/src/types/core.ts +3 -3
- package/src/types/events.ts +4 -3
- package/src/types/index.ts +7 -7
- package/src/types/subagent.ts +1 -1
- package/src/utils/eviction.ts +2 -2
- package/src/utils/index.ts +5 -5
- package/src/utils/summarization.ts +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepagentsdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Deep Agent implementation using Vercel AI SDK - build controllable AI agents with planning, filesystem, and subagent capabilities",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
},
|
|
17
17
|
"./cli": {
|
|
18
18
|
"import": "./src/cli/index.ts"
|
|
19
|
+
},
|
|
20
|
+
"./elements": {
|
|
21
|
+
"import": "./src/adapters/elements/index.ts",
|
|
22
|
+
"types": "./src/adapters/elements/index.ts"
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
"files": [
|
|
@@ -40,13 +44,13 @@
|
|
|
40
44
|
"url": "https://github.com/chrispangg/deepagentsdk/issues"
|
|
41
45
|
},
|
|
42
46
|
"dependencies": {
|
|
43
|
-
"@ai-sdk/anthropic": "^3.0.
|
|
44
|
-
"@ai-sdk/openai": "^3.0.
|
|
45
|
-
"@ai-sdk/react": "^3.0.
|
|
47
|
+
"@ai-sdk/anthropic": "^3.0.9",
|
|
48
|
+
"@ai-sdk/openai": "^3.0.7",
|
|
49
|
+
"@ai-sdk/react": "^3.0.9",
|
|
46
50
|
"@inkjs/ui": "^1.0.0",
|
|
47
51
|
"@mozilla/readability": "^0.6.0",
|
|
48
52
|
"@tavily/core": "^0.6.1",
|
|
49
|
-
"ai": "^6.0.
|
|
53
|
+
"ai": "^6.0.19",
|
|
50
54
|
"fast-glob": "^3.3.3",
|
|
51
55
|
"ink": "^5.1.0",
|
|
52
56
|
"jsdom": "^25.0.1",
|
|
@@ -63,6 +67,7 @@
|
|
|
63
67
|
"@opentelemetry/instrumentation": "^0.208.0",
|
|
64
68
|
"@opentelemetry/sdk-logs": "^0.208.0",
|
|
65
69
|
"@opentelemetry/sdk-node": "^0.208.0",
|
|
70
|
+
"@testing-library/react": "^16.3.1",
|
|
66
71
|
"@types/bun": "latest",
|
|
67
72
|
"@types/jsdom": "^21.1.7",
|
|
68
73
|
"@types/micromatch": "^4.0.9",
|
|
@@ -71,6 +76,7 @@
|
|
|
71
76
|
"@vercel/otel": "^2.1.0",
|
|
72
77
|
"install": "^0.13.0",
|
|
73
78
|
"langfuse-vercel": "^3.38.6",
|
|
79
|
+
"react-dom": "^18.2.0",
|
|
74
80
|
"typescript": "^5.7.3"
|
|
75
81
|
},
|
|
76
82
|
"peerDependencies": {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI SDK Elements adapter for deepagentsdk
|
|
3
|
+
*
|
|
4
|
+
* This adapter enables deepagentsdk to work seamlessly with Vercel AI SDK Elements
|
|
5
|
+
* UI components by transforming agent events to the UIMessage format expected by Elements.
|
|
6
|
+
*
|
|
7
|
+
* @module adapters/elements
|
|
8
|
+
* @see https://ai-sdk.dev/elements
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { useElementsAdapter } from "./useElementsAdapter";
|
|
12
|
+
export type { UseElementsAdapterOptions } from "./useElementsAdapter";
|
|
13
|
+
|
|
14
|
+
export { mapAgentStatusToUIStatus } from "./statusAdapter";
|
|
15
|
+
export {
|
|
16
|
+
convertEventsToUIMessages,
|
|
17
|
+
extractToolParts,
|
|
18
|
+
} from "./messageAdapter";
|
|
19
|
+
|
|
20
|
+
export type {
|
|
21
|
+
UIMessage,
|
|
22
|
+
UIMessagePart,
|
|
23
|
+
UIStatus,
|
|
24
|
+
PromptInputMessage,
|
|
25
|
+
ToolUIPart,
|
|
26
|
+
UseElementsAdapterReturn,
|
|
27
|
+
} from "./types";
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message transformation adapter for AI SDK Elements
|
|
3
|
+
*
|
|
4
|
+
* Converts deepagentsdk events to Elements UIMessage format
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AgentEventLog } from "../../cli/hooks/useAgent";
|
|
8
|
+
import type { UIMessage, UIMessagePart, UIStatus } from "./types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Converts agent event log to UIMessage format expected by Elements
|
|
12
|
+
*
|
|
13
|
+
* @param events - Array of agent events from useAgent hook
|
|
14
|
+
* @param streamingText - Current streaming text (if any)
|
|
15
|
+
* @param uiStatus - Current UI status
|
|
16
|
+
* @returns Array of UIMessage objects for Elements Message component
|
|
17
|
+
*
|
|
18
|
+
* Conversion logic:
|
|
19
|
+
* 1. Group events by role (user/assistant)
|
|
20
|
+
* 2. Convert each event type to appropriate UIMessagePart
|
|
21
|
+
* 3. Handle streaming text as in-progress message
|
|
22
|
+
* 4. Preserve event order and tool call/result pairing
|
|
23
|
+
*/
|
|
24
|
+
export function convertEventsToUIMessages(
|
|
25
|
+
events: AgentEventLog[],
|
|
26
|
+
streamingText: string,
|
|
27
|
+
uiStatus: UIStatus
|
|
28
|
+
): UIMessage[] {
|
|
29
|
+
const messages: UIMessage[] = [];
|
|
30
|
+
let currentAssistantParts: UIMessagePart[] = [];
|
|
31
|
+
let messageIdCounter = 0;
|
|
32
|
+
|
|
33
|
+
const generateMessageId = (): string => {
|
|
34
|
+
return `msg-${Date.now()}-${++messageIdCounter}`;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
for (const eventLog of events) {
|
|
38
|
+
const event = eventLog.event;
|
|
39
|
+
|
|
40
|
+
switch (event.type) {
|
|
41
|
+
case "user-message":
|
|
42
|
+
// Flush any pending assistant parts before user message
|
|
43
|
+
if (currentAssistantParts.length > 0) {
|
|
44
|
+
messages.push({
|
|
45
|
+
id: generateMessageId(),
|
|
46
|
+
role: "assistant",
|
|
47
|
+
parts: currentAssistantParts,
|
|
48
|
+
status: "ready",
|
|
49
|
+
});
|
|
50
|
+
currentAssistantParts = [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Add user message
|
|
54
|
+
messages.push({
|
|
55
|
+
id: eventLog.id,
|
|
56
|
+
role: "user",
|
|
57
|
+
parts: [{ type: "text", text: event.content }],
|
|
58
|
+
status: "ready",
|
|
59
|
+
});
|
|
60
|
+
break;
|
|
61
|
+
|
|
62
|
+
case "text-segment":
|
|
63
|
+
// Add text segment as separate text part
|
|
64
|
+
currentAssistantParts.push({
|
|
65
|
+
type: "text",
|
|
66
|
+
text: event.text,
|
|
67
|
+
});
|
|
68
|
+
break;
|
|
69
|
+
|
|
70
|
+
case "tool-call":
|
|
71
|
+
// Add tool call part
|
|
72
|
+
currentAssistantParts.push({
|
|
73
|
+
type: "tool-call",
|
|
74
|
+
toolCallId: event.toolCallId,
|
|
75
|
+
toolName: event.toolName,
|
|
76
|
+
args: event.args,
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
|
|
80
|
+
case "tool-result":
|
|
81
|
+
// Add tool result part
|
|
82
|
+
currentAssistantParts.push({
|
|
83
|
+
type: "tool-result",
|
|
84
|
+
toolCallId: event.toolCallId,
|
|
85
|
+
toolName: event.toolName,
|
|
86
|
+
result: event.result,
|
|
87
|
+
isError: event.isError,
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
|
|
91
|
+
// Ignore other event types for message rendering
|
|
92
|
+
// (they're handled separately by Elements components like Task, etc.)
|
|
93
|
+
default:
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Add streaming text as in-progress assistant message
|
|
99
|
+
if (streamingText || currentAssistantParts.length > 0) {
|
|
100
|
+
if (streamingText) {
|
|
101
|
+
currentAssistantParts.push({ type: "text", text: streamingText });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Determine status for current message
|
|
105
|
+
let messageStatus: UIStatus = "ready";
|
|
106
|
+
if (uiStatus === "streaming") {
|
|
107
|
+
messageStatus = "streaming";
|
|
108
|
+
} else if (uiStatus === "submitted") {
|
|
109
|
+
messageStatus = "submitted";
|
|
110
|
+
} else if (uiStatus === "error") {
|
|
111
|
+
messageStatus = "error";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
messages.push({
|
|
115
|
+
id: generateMessageId(),
|
|
116
|
+
role: "assistant",
|
|
117
|
+
parts: currentAssistantParts,
|
|
118
|
+
status: messageStatus,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return messages;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Extracts tool parts from the most recent assistant message
|
|
127
|
+
*
|
|
128
|
+
* @param messages - UIMessage array
|
|
129
|
+
* @returns Array of tool parts (tool-call and tool-result)
|
|
130
|
+
*/
|
|
131
|
+
export function extractToolParts(messages: UIMessage[]) {
|
|
132
|
+
// Get last assistant message
|
|
133
|
+
const lastAssistantMessage = [...messages]
|
|
134
|
+
.reverse()
|
|
135
|
+
.find((m) => m.role === "assistant");
|
|
136
|
+
|
|
137
|
+
if (!lastAssistantMessage) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Extract only tool-related parts
|
|
142
|
+
return lastAssistantMessage.parts
|
|
143
|
+
.filter(
|
|
144
|
+
(part): part is Extract<UIMessagePart, { type: "tool-call" | "tool-result" }> =>
|
|
145
|
+
part.type === "tool-call" || part.type === "tool-result"
|
|
146
|
+
)
|
|
147
|
+
.map((part) => {
|
|
148
|
+
if (part.type === "tool-call") {
|
|
149
|
+
return {
|
|
150
|
+
type: "tool-call" as const,
|
|
151
|
+
toolCallId: part.toolCallId,
|
|
152
|
+
toolName: part.toolName,
|
|
153
|
+
args: part.args,
|
|
154
|
+
};
|
|
155
|
+
} else {
|
|
156
|
+
return {
|
|
157
|
+
type: "tool-result" as const,
|
|
158
|
+
toolCallId: part.toolCallId,
|
|
159
|
+
toolName: part.toolName,
|
|
160
|
+
result: part.result,
|
|
161
|
+
isError: part.isError,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status mapping adapter for AI SDK Elements
|
|
3
|
+
*
|
|
4
|
+
* Maps deepagentsdk AgentStatus to Elements UIStatus
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { AgentStatus } from "../../cli/hooks/useAgent";
|
|
8
|
+
import type { UIStatus } from "./types";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Maps deepagentsdk AgentStatus to Elements UIStatus
|
|
12
|
+
*
|
|
13
|
+
* @param agentStatus - The agent status from useAgent hook
|
|
14
|
+
* @returns The corresponding UI status for Elements components
|
|
15
|
+
*
|
|
16
|
+
* Mapping rules:
|
|
17
|
+
* - idle/done → ready (agent is waiting for input)
|
|
18
|
+
* - thinking/tool-call/subagent → submitted (agent is processing)
|
|
19
|
+
* - streaming → streaming (agent is generating text)
|
|
20
|
+
* - error → error (an error occurred)
|
|
21
|
+
*/
|
|
22
|
+
export function mapAgentStatusToUIStatus(
|
|
23
|
+
agentStatus: AgentStatus
|
|
24
|
+
): UIStatus {
|
|
25
|
+
switch (agentStatus) {
|
|
26
|
+
case "thinking":
|
|
27
|
+
case "tool-call":
|
|
28
|
+
case "subagent":
|
|
29
|
+
return "submitted";
|
|
30
|
+
case "streaming":
|
|
31
|
+
return "streaming";
|
|
32
|
+
case "error":
|
|
33
|
+
return "error";
|
|
34
|
+
case "idle":
|
|
35
|
+
case "done":
|
|
36
|
+
default:
|
|
37
|
+
return "ready";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for AI SDK Elements adapter
|
|
3
|
+
*
|
|
4
|
+
* These types align with Vercel AI SDK Elements UI component expectations.
|
|
5
|
+
* @see https://ai-sdk.dev/elements
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* UI message part types that Elements components expect
|
|
10
|
+
*/
|
|
11
|
+
export type UIMessagePart =
|
|
12
|
+
| {
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
| {
|
|
17
|
+
type: "tool-call";
|
|
18
|
+
toolCallId: string;
|
|
19
|
+
toolName: string;
|
|
20
|
+
args: unknown;
|
|
21
|
+
}
|
|
22
|
+
| {
|
|
23
|
+
type: "tool-result";
|
|
24
|
+
toolCallId: string;
|
|
25
|
+
toolName: string;
|
|
26
|
+
result: unknown;
|
|
27
|
+
isError?: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* UI message format expected by Elements Message component
|
|
32
|
+
*/
|
|
33
|
+
export interface UIMessage {
|
|
34
|
+
id: string;
|
|
35
|
+
role: "user" | "assistant";
|
|
36
|
+
parts: UIMessagePart[];
|
|
37
|
+
status: "submitted" | "streaming" | "ready" | "error";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* UI status that Elements components use
|
|
42
|
+
*/
|
|
43
|
+
export type UIStatus = "submitted" | "streaming" | "ready" | "error";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* PromptInput component message format
|
|
47
|
+
*/
|
|
48
|
+
export interface PromptInputMessage {
|
|
49
|
+
text: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Tool parts extracted from current message for Tool component
|
|
54
|
+
*/
|
|
55
|
+
export interface ToolUIPart {
|
|
56
|
+
type: "tool-call" | "tool-result";
|
|
57
|
+
toolCallId: string;
|
|
58
|
+
toolName: string;
|
|
59
|
+
args?: unknown;
|
|
60
|
+
result?: unknown;
|
|
61
|
+
isError?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Return type for useElementsAdapter hook
|
|
66
|
+
*/
|
|
67
|
+
export interface UseElementsAdapterReturn {
|
|
68
|
+
/**
|
|
69
|
+
* Messages formatted for Elements Message component
|
|
70
|
+
*/
|
|
71
|
+
uiMessages: UIMessage[];
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Current UI status for Elements components
|
|
75
|
+
*/
|
|
76
|
+
uiStatus: UIStatus;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Tool parts from current message for Tool component
|
|
80
|
+
*/
|
|
81
|
+
toolParts: ToolUIPart[];
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Send a message (compatible with PromptInput onSubmit)
|
|
85
|
+
*/
|
|
86
|
+
sendMessage: (message: PromptInputMessage) => Promise<void>;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Abort current streaming
|
|
90
|
+
*/
|
|
91
|
+
abort: () => void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Clear all messages
|
|
95
|
+
*/
|
|
96
|
+
clear: () => void;
|
|
97
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook adapter for AI SDK Elements
|
|
3
|
+
*
|
|
4
|
+
* Provides Elements-compatible interface for deepagentsdk
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback, useRef, useMemo } from "react";
|
|
8
|
+
import { createDeepAgent } from "../../agent";
|
|
9
|
+
import type { LanguageModel, ToolSet } from "ai";
|
|
10
|
+
import type {
|
|
11
|
+
BackendProtocol,
|
|
12
|
+
DeepAgentState,
|
|
13
|
+
DeepAgentEvent,
|
|
14
|
+
} from "../../types";
|
|
15
|
+
import {
|
|
16
|
+
convertEventsToUIMessages,
|
|
17
|
+
extractToolParts,
|
|
18
|
+
} from "./messageAdapter";
|
|
19
|
+
import { mapAgentStatusToUIStatus } from "./statusAdapter";
|
|
20
|
+
import type { UseElementsAdapterReturn, PromptInputMessage } from "./types";
|
|
21
|
+
import type { AgentStatus, AgentEventLog } from "../../cli/hooks/useAgent";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Options for useElementsAdapter hook
|
|
25
|
+
*/
|
|
26
|
+
export interface UseElementsAdapterOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Language model instance from AI SDK provider
|
|
29
|
+
*/
|
|
30
|
+
model: LanguageModel;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Backend for state management
|
|
34
|
+
*/
|
|
35
|
+
backend: BackendProtocol;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Optional tools to provide to the agent
|
|
39
|
+
*/
|
|
40
|
+
tools?: ToolSet;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Maximum number of tool loop iterations
|
|
44
|
+
* @default 10
|
|
45
|
+
*/
|
|
46
|
+
maxSteps?: number;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* System prompt for the agent
|
|
50
|
+
*/
|
|
51
|
+
systemPrompt?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let eventCounter = 0;
|
|
55
|
+
|
|
56
|
+
function createEventId(): string {
|
|
57
|
+
return `event-${++eventCounter}`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Hook that adapts deepagentsdk to work with AI SDK Elements UI components
|
|
62
|
+
*
|
|
63
|
+
* @param options - Configuration options
|
|
64
|
+
* @returns Elements-compatible interface
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```tsx
|
|
68
|
+
* import { useElementsAdapter } from 'deepagentsdk/elements';
|
|
69
|
+
* import { Conversation, Message, PromptInput } from '@/components/ai-elements';
|
|
70
|
+
*
|
|
71
|
+
* function Chat() {
|
|
72
|
+
* const { uiMessages, sendMessage } = useElementsAdapter({
|
|
73
|
+
* model,
|
|
74
|
+
* backend
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <Conversation>
|
|
79
|
+
* {uiMessages.map(msg => <Message key={msg.id} from={msg.role} />)}
|
|
80
|
+
* <PromptInput onSubmit={sendMessage} />
|
|
81
|
+
* </Conversation>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export function useElementsAdapter(
|
|
87
|
+
options: UseElementsAdapterOptions
|
|
88
|
+
): UseElementsAdapterReturn {
|
|
89
|
+
const { model, backend, tools, maxSteps = 10, systemPrompt } = options;
|
|
90
|
+
|
|
91
|
+
const [status, setStatus] = useState<AgentStatus>("idle");
|
|
92
|
+
const [streamingText, setStreamingText] = useState("");
|
|
93
|
+
const [events, setEvents] = useState<AgentEventLog[]>([]);
|
|
94
|
+
const [state, setState] = useState<DeepAgentState>({
|
|
95
|
+
todos: [],
|
|
96
|
+
files: {},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const abortControllerRef = useRef<AbortController | null>(null);
|
|
100
|
+
const accumulatedTextRef = useRef("");
|
|
101
|
+
|
|
102
|
+
// Create agent instance
|
|
103
|
+
const agentRef = useRef(
|
|
104
|
+
createDeepAgent({
|
|
105
|
+
model,
|
|
106
|
+
maxSteps,
|
|
107
|
+
systemPrompt,
|
|
108
|
+
backend,
|
|
109
|
+
tools,
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const addEvent = useCallback(
|
|
114
|
+
(event: DeepAgentEvent | { type: "text-segment"; text: string }) => {
|
|
115
|
+
setEvents((prev) => [
|
|
116
|
+
...prev,
|
|
117
|
+
{
|
|
118
|
+
id: createEventId(),
|
|
119
|
+
type: event.type,
|
|
120
|
+
event,
|
|
121
|
+
timestamp: new Date(),
|
|
122
|
+
},
|
|
123
|
+
]);
|
|
124
|
+
},
|
|
125
|
+
[]
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Flush accumulated text as a text-segment event
|
|
129
|
+
const flushTextSegment = useCallback(() => {
|
|
130
|
+
if (accumulatedTextRef.current.trim()) {
|
|
131
|
+
addEvent({
|
|
132
|
+
type: "text-segment",
|
|
133
|
+
text: accumulatedTextRef.current,
|
|
134
|
+
});
|
|
135
|
+
accumulatedTextRef.current = "";
|
|
136
|
+
setStreamingText("");
|
|
137
|
+
}
|
|
138
|
+
}, [addEvent]);
|
|
139
|
+
|
|
140
|
+
const sendMessage = async (message: PromptInputMessage): Promise<void> => {
|
|
141
|
+
if (!message.text.trim()) {
|
|
142
|
+
return; // Ignore empty messages
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Reset for new generation
|
|
146
|
+
setStatus("thinking");
|
|
147
|
+
setStreamingText("");
|
|
148
|
+
accumulatedTextRef.current = "";
|
|
149
|
+
|
|
150
|
+
// Add user message to events
|
|
151
|
+
addEvent({ type: "user-message", content: message.text });
|
|
152
|
+
|
|
153
|
+
// Create new abort controller
|
|
154
|
+
abortControllerRef.current = new AbortController();
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
for await (const event of agentRef.current.streamWithEvents({
|
|
158
|
+
messages: [{ role: "user", content: message.text }],
|
|
159
|
+
state,
|
|
160
|
+
abortSignal: abortControllerRef.current.signal,
|
|
161
|
+
})) {
|
|
162
|
+
switch (event.type) {
|
|
163
|
+
case "text":
|
|
164
|
+
setStatus("streaming");
|
|
165
|
+
accumulatedTextRef.current += event.text;
|
|
166
|
+
setStreamingText(accumulatedTextRef.current);
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
case "step-start":
|
|
170
|
+
if (event.stepNumber > 1) {
|
|
171
|
+
addEvent(event);
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
|
|
175
|
+
case "tool-call":
|
|
176
|
+
flushTextSegment();
|
|
177
|
+
setStatus("tool-call");
|
|
178
|
+
addEvent(event);
|
|
179
|
+
break;
|
|
180
|
+
|
|
181
|
+
case "tool-result":
|
|
182
|
+
addEvent(event);
|
|
183
|
+
break;
|
|
184
|
+
|
|
185
|
+
case "todos-changed":
|
|
186
|
+
flushTextSegment();
|
|
187
|
+
setStatus("tool-call");
|
|
188
|
+
setState((prev) => ({ ...prev, todos: event.todos }));
|
|
189
|
+
addEvent(event);
|
|
190
|
+
break;
|
|
191
|
+
|
|
192
|
+
case "done":
|
|
193
|
+
flushTextSegment();
|
|
194
|
+
setStatus("done");
|
|
195
|
+
setState(event.state);
|
|
196
|
+
addEvent(event);
|
|
197
|
+
break;
|
|
198
|
+
|
|
199
|
+
case "error":
|
|
200
|
+
flushTextSegment();
|
|
201
|
+
setStatus("error");
|
|
202
|
+
addEvent(event);
|
|
203
|
+
break;
|
|
204
|
+
|
|
205
|
+
default:
|
|
206
|
+
addEvent(event);
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
setStatus("idle");
|
|
212
|
+
} catch (err) {
|
|
213
|
+
if ((err as Error).name === "AbortError") {
|
|
214
|
+
flushTextSegment();
|
|
215
|
+
setStatus("idle");
|
|
216
|
+
} else {
|
|
217
|
+
flushTextSegment();
|
|
218
|
+
setStatus("error");
|
|
219
|
+
}
|
|
220
|
+
} finally {
|
|
221
|
+
abortControllerRef.current = null;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const abort = useCallback(() => {
|
|
226
|
+
if (abortControllerRef.current) {
|
|
227
|
+
abortControllerRef.current.abort();
|
|
228
|
+
setStatus("idle");
|
|
229
|
+
}
|
|
230
|
+
}, []);
|
|
231
|
+
|
|
232
|
+
const clear = useCallback(() => {
|
|
233
|
+
setEvents([]);
|
|
234
|
+
setStreamingText("");
|
|
235
|
+
setStatus("idle");
|
|
236
|
+
}, []);
|
|
237
|
+
|
|
238
|
+
// Convert agent status to UI status
|
|
239
|
+
const uiStatus = useMemo(
|
|
240
|
+
() => mapAgentStatusToUIStatus(status),
|
|
241
|
+
[status]
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
// Convert events to UI messages
|
|
245
|
+
const uiMessages = useMemo(
|
|
246
|
+
() => convertEventsToUIMessages(events, streamingText, uiStatus),
|
|
247
|
+
[events, streamingText, uiStatus]
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// Extract tool parts from current message
|
|
251
|
+
const toolParts = useMemo(() => extractToolParts(uiMessages), [uiMessages]);
|
|
252
|
+
|
|
253
|
+
return {
|
|
254
|
+
uiMessages,
|
|
255
|
+
uiStatus,
|
|
256
|
+
toolParts,
|
|
257
|
+
sendMessage,
|
|
258
|
+
abort,
|
|
259
|
+
clear,
|
|
260
|
+
};
|
|
261
|
+
}
|
package/src/agent.ts
CHANGED
|
@@ -961,22 +961,50 @@ export class DeepAgent {
|
|
|
961
961
|
// Yield step start event
|
|
962
962
|
yield { type: "step-start", stepNumber: 1 };
|
|
963
963
|
|
|
964
|
-
// Stream text
|
|
965
|
-
for await (const chunk of result.
|
|
964
|
+
// Stream all chunks (text, tool calls, etc.)
|
|
965
|
+
for await (const chunk of result.fullStream) {
|
|
966
966
|
// First, yield any queued events from tool executions
|
|
967
967
|
while (eventQueue.length > 0) {
|
|
968
968
|
const event = eventQueue.shift()!;
|
|
969
969
|
yield event;
|
|
970
|
-
|
|
970
|
+
|
|
971
971
|
// If a step finished, yield the next step start
|
|
972
972
|
if (event.type === "step-finish") {
|
|
973
973
|
yield { type: "step-start", stepNumber: event.stepNumber + 1 };
|
|
974
974
|
}
|
|
975
975
|
}
|
|
976
976
|
|
|
977
|
-
//
|
|
978
|
-
if (chunk) {
|
|
979
|
-
yield { type: "text", text: chunk };
|
|
977
|
+
// Handle different chunk types from fullStream
|
|
978
|
+
if (chunk.type === "text-delta") {
|
|
979
|
+
yield { type: "text", text: chunk.text };
|
|
980
|
+
} else if (chunk.type === "tool-call") {
|
|
981
|
+
// Emit tool-call event for UI
|
|
982
|
+
// Note: chunk has input property (AI SDK v6), but we use args for our event type
|
|
983
|
+
yield {
|
|
984
|
+
type: "tool-call",
|
|
985
|
+
toolName: chunk.toolName,
|
|
986
|
+
toolCallId: chunk.toolCallId,
|
|
987
|
+
args: chunk.input,
|
|
988
|
+
} as DeepAgentEvent;
|
|
989
|
+
} else if (chunk.type === "tool-result") {
|
|
990
|
+
// Emit tool-result event for UI
|
|
991
|
+
// Note: chunk has output property (AI SDK v6), but we use result for our event type
|
|
992
|
+
yield {
|
|
993
|
+
type: "tool-result",
|
|
994
|
+
toolName: chunk.toolName,
|
|
995
|
+
toolCallId: chunk.toolCallId,
|
|
996
|
+
result: chunk.output,
|
|
997
|
+
isError: false,
|
|
998
|
+
} as DeepAgentEvent;
|
|
999
|
+
} else if (chunk.type === "tool-error") {
|
|
1000
|
+
// Emit tool-result event with error flag for UI
|
|
1001
|
+
yield {
|
|
1002
|
+
type: "tool-result",
|
|
1003
|
+
toolName: chunk.toolName,
|
|
1004
|
+
toolCallId: chunk.toolCallId,
|
|
1005
|
+
result: chunk.error,
|
|
1006
|
+
isError: true,
|
|
1007
|
+
} as DeepAgentEvent;
|
|
980
1008
|
}
|
|
981
1009
|
}
|
|
982
1010
|
|
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
FileInfo,
|
|
14
14
|
GrepMatch,
|
|
15
15
|
WriteResult,
|
|
16
|
-
} from "../types
|
|
16
|
+
} from "../types";
|
|
17
17
|
import {
|
|
18
18
|
createFileData,
|
|
19
19
|
fileDataToString,
|
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
grepMatchesFromFiles,
|
|
23
23
|
performStringReplacement,
|
|
24
24
|
updateFileData,
|
|
25
|
-
} from "./utils
|
|
25
|
+
} from "./utils";
|
|
26
26
|
import {
|
|
27
27
|
FILE_NOT_FOUND,
|
|
28
28
|
FILE_ALREADY_EXISTS,
|
|
29
|
-
} from "../constants/errors
|
|
29
|
+
} from "../constants/errors";
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Generic key-value store interface for persistent storage.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Box, Text } from "ink";
|
|
6
|
-
import { emoji, colors } from "../theme
|
|
7
|
-
import type { FileInfo } from "../../types
|
|
6
|
+
import { emoji, colors } from "../theme";
|
|
7
|
+
import type { FileInfo } from "../../types";
|
|
8
8
|
|
|
9
9
|
interface FilePreviewProps {
|
|
10
10
|
/** File path */
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import React, { useState, useRef } from "react";
|
|
6
6
|
import { Box, Text, useInput } from "ink";
|
|
7
|
-
import { colors } from "../theme
|
|
8
|
-
import { SlashMenu } from "./SlashMenu
|
|
7
|
+
import { colors } from "../theme";
|
|
8
|
+
import { SlashMenu } from "./SlashMenu";
|
|
9
9
|
|
|
10
10
|
interface InputProps {
|
|
11
11
|
/** Called when user submits input */
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import React from "react";
|
|
6
6
|
import { Box, Text } from "ink";
|
|
7
|
-
import { colors } from "../theme
|
|
8
|
-
import { ToolCallSummary } from "./ToolCallSummary
|
|
7
|
+
import { colors } from "../theme";
|
|
8
|
+
import { ToolCallSummary } from "./ToolCallSummary";
|
|
9
9
|
|
|
10
10
|
export type MessageRole = "user" | "assistant";
|
|
11
11
|
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
import React, { useState, useEffect, useMemo } from "react";
|
|
6
6
|
import { Box, Text, useInput } from "ink";
|
|
7
7
|
import { Spinner } from "@inkjs/ui";
|
|
8
|
-
import { colors, emoji } from "../theme
|
|
8
|
+
import { colors, emoji } from "../theme";
|
|
9
9
|
import {
|
|
10
10
|
getModelsByProvider,
|
|
11
11
|
detectAvailableProviders,
|
|
12
12
|
type AvailableModel,
|
|
13
|
-
} from "../utils/model-list
|
|
13
|
+
} from "../utils/model-list";
|
|
14
14
|
|
|
15
15
|
interface ModelSelectionPanelProps {
|
|
16
16
|
currentModel?: string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Box, Text } from "ink";
|
|
6
|
-
import { colors, filterCommands, type SlashCommand } from "../theme
|
|
6
|
+
import { colors, filterCommands, type SlashCommand } from "../theme";
|
|
7
7
|
|
|
8
8
|
interface SlashMenuProps {
|
|
9
9
|
/** Current input value to filter commands */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Box, Text } from "ink";
|
|
6
6
|
import { Spinner, StatusMessage } from "@inkjs/ui";
|
|
7
|
-
import { emoji, colors } from "../theme
|
|
7
|
+
import { emoji, colors } from "../theme";
|
|
8
8
|
|
|
9
9
|
interface SubagentStartProps {
|
|
10
10
|
/** Subagent name */
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { Box, Text } from "ink";
|
|
6
6
|
import { Badge } from "@inkjs/ui";
|
|
7
|
-
import { emoji, colors } from "../theme
|
|
8
|
-
import type { TodoItem } from "../../types
|
|
7
|
+
import { emoji, colors } from "../theme";
|
|
8
|
+
import type { TodoItem } from "../../types";
|
|
9
9
|
|
|
10
10
|
interface TodoListProps {
|
|
11
11
|
todos: TodoItem[];
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import React, { useState } from "react";
|
|
6
6
|
import { Box, Text, useInput } from "ink";
|
|
7
|
-
import { colors, emoji } from "../theme
|
|
8
|
-
import type { ToolCallData } from "./Message
|
|
7
|
+
import { colors, emoji } from "../theme";
|
|
8
|
+
import type { ToolCallData } from "./Message";
|
|
9
9
|
|
|
10
10
|
interface ToolCallSummaryProps {
|
|
11
11
|
/** Array of tool calls to display */
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Export all CLI components.
|
|
3
3
|
*/
|
|
4
|
-
export { Welcome, WelcomeHint } from "./Welcome
|
|
5
|
-
export { Input } from "./Input
|
|
6
|
-
export { SlashMenu, SlashMenuPanel } from "./SlashMenu
|
|
7
|
-
export { Message, StreamingMessage, type MessageData, type MessageRole, type ToolCallData } from "./Message
|
|
8
|
-
export { TodoList, TodosChanged } from "./TodoList
|
|
9
|
-
export { FilePreview, FileWritten, FileEdited, FileRead, LsResult, GlobResult, GrepResult, FileList } from "./FilePreview
|
|
4
|
+
export { Welcome, WelcomeHint } from "./Welcome";
|
|
5
|
+
export { Input } from "./Input";
|
|
6
|
+
export { SlashMenu, SlashMenuPanel } from "./SlashMenu";
|
|
7
|
+
export { Message, StreamingMessage, type MessageData, type MessageRole, type ToolCallData } from "./Message";
|
|
8
|
+
export { TodoList, TodosChanged } from "./TodoList";
|
|
9
|
+
export { FilePreview, FileWritten, FileEdited, FileRead, LsResult, GlobResult, GrepResult, FileList } from "./FilePreview";
|
|
10
10
|
export {
|
|
11
11
|
ToolCall,
|
|
12
12
|
ToolResult,
|
|
@@ -14,11 +14,11 @@ export {
|
|
|
14
14
|
ThinkingIndicator,
|
|
15
15
|
DoneIndicator,
|
|
16
16
|
ErrorDisplay,
|
|
17
|
-
} from "./ToolCall
|
|
18
|
-
export { SubagentStart, SubagentFinish, SubagentRunning } from "./Subagent
|
|
19
|
-
export { StatusBar } from "./StatusBar
|
|
20
|
-
export { ToolCallSummary, InlineToolCall } from "./ToolCallSummary
|
|
21
|
-
export { ModelSelectionPanel } from "./ModelSelection
|
|
22
|
-
export { ApiKeyInputPanel, ApiKeyStatus } from "./ApiKeyInput
|
|
23
|
-
export { ToolApproval } from "./ToolApproval
|
|
17
|
+
} from "./ToolCall";
|
|
18
|
+
export { SubagentStart, SubagentFinish, SubagentRunning } from "./Subagent";
|
|
19
|
+
export { StatusBar } from "./StatusBar";
|
|
20
|
+
export { ToolCallSummary, InlineToolCall } from "./ToolCallSummary";
|
|
21
|
+
export { ModelSelectionPanel } from "./ModelSelection";
|
|
22
|
+
export { ApiKeyInputPanel, ApiKeyStatus } from "./ApiKeyInput";
|
|
23
|
+
export { ToolApproval } from "./ToolApproval";
|
|
24
24
|
|
package/src/cli/hooks/index.ts
CHANGED
|
@@ -9,12 +9,12 @@ import type {
|
|
|
9
9
|
ModelMessage,
|
|
10
10
|
SummarizationConfig,
|
|
11
11
|
InterruptOnConfig,
|
|
12
|
-
} from "../../types
|
|
13
|
-
import type { BaseCheckpointSaver } from "../../checkpointer/types
|
|
14
|
-
import { createDeepAgent } from "../../agent
|
|
15
|
-
import { parseModelString } from "../../utils/model-parser
|
|
16
|
-
import type { SandboxBackendProtocol } from "../../types
|
|
17
|
-
import type { ToolCallData } from "../components/Message
|
|
12
|
+
} from "../../types";
|
|
13
|
+
import type { BaseCheckpointSaver } from "../../checkpointer/types";
|
|
14
|
+
import { createDeepAgent } from "../../agent";
|
|
15
|
+
import { parseModelString } from "../../utils/model-parser";
|
|
16
|
+
import type { SandboxBackendProtocol } from "../../types";
|
|
17
|
+
import type { ToolCallData } from "../components/Message";
|
|
18
18
|
import { useEffect } from "react";
|
|
19
19
|
|
|
20
20
|
export type AgentStatus =
|
package/src/cli/index.tsx
CHANGED
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
|
|
13
13
|
import React, { useState, useEffect, useCallback } from "react";
|
|
14
14
|
import { render, useApp, useInput, Box, Text, Static } from "ink";
|
|
15
|
-
import { LocalSandbox } from "../backends/local-sandbox
|
|
15
|
+
import { LocalSandbox } from "../backends/local-sandbox";
|
|
16
16
|
import {
|
|
17
17
|
DEFAULT_EVICTION_TOKEN_LIMIT,
|
|
18
18
|
DEFAULT_SUMMARIZATION_THRESHOLD,
|
|
19
19
|
DEFAULT_KEEP_MESSAGES,
|
|
20
20
|
CONTEXT_WINDOW,
|
|
21
21
|
} from "../constants/limits";
|
|
22
|
-
import { FileSaver } from "../checkpointer/file-saver
|
|
23
|
-
import { useAgent, type AgentEventLog } from "./hooks/useAgent
|
|
22
|
+
import { FileSaver } from "../checkpointer/file-saver";
|
|
23
|
+
import { useAgent, type AgentEventLog } from "./hooks/useAgent";
|
|
24
24
|
import {
|
|
25
25
|
Welcome,
|
|
26
26
|
WelcomeHint,
|
|
@@ -49,10 +49,10 @@ import {
|
|
|
49
49
|
ApiKeyInputPanel,
|
|
50
50
|
ToolApproval,
|
|
51
51
|
type MessageData,
|
|
52
|
-
} from "./components/index
|
|
53
|
-
import { parseCommand, colors, SLASH_COMMANDS } from "./theme
|
|
54
|
-
import type { FileInfo } from "../types
|
|
55
|
-
import { estimateMessagesTokens } from "../utils/summarization
|
|
52
|
+
} from "./components/index";
|
|
53
|
+
import { parseCommand, colors, SLASH_COMMANDS } from "./theme";
|
|
54
|
+
import type { FileInfo } from "../types";
|
|
55
|
+
import { estimateMessagesTokens } from "../utils/summarization";
|
|
56
56
|
|
|
57
57
|
// ============================================================================
|
|
58
58
|
// CLI Arguments
|
|
@@ -2,7 +2,7 @@ import * as fs from 'node:fs/promises';
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import type { LanguageModelMiddleware } from 'ai';
|
|
5
|
-
import { findGitRoot } from '../utils/project-detection
|
|
5
|
+
import { findGitRoot } from '../utils/project-detection';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Configuration options for agent memory middleware.
|
package/src/skills/load.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import type { SkillMetadata, SkillLoadOptions } from "./types";
|
|
5
|
-
import { findGitRoot } from "../utils/project-detection
|
|
5
|
+
import { findGitRoot } from "../utils/project-detection";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Parse YAML frontmatter from a SKILL.md file.
|
package/src/types/backend.ts
CHANGED
package/src/types/core.ts
CHANGED
|
@@ -10,9 +10,9 @@ import type {
|
|
|
10
10
|
ToolLoopAgentSettings,
|
|
11
11
|
} from "ai";
|
|
12
12
|
import type { z } from "zod";
|
|
13
|
-
import type { BaseCheckpointSaver } from "../checkpointer/types
|
|
14
|
-
import type { BackendProtocol, BackendFactory } from "./backend
|
|
15
|
-
import type { SubAgent, InterruptOnConfig } from "./subagent
|
|
13
|
+
import type { BaseCheckpointSaver } from "../checkpointer/types";
|
|
14
|
+
import type { BackendProtocol, BackendFactory } from "./backend";
|
|
15
|
+
import type { SubAgent, InterruptOnConfig } from "./subagent";
|
|
16
16
|
|
|
17
17
|
// Re-export LanguageModel for convenience
|
|
18
18
|
export type { LanguageModel };
|
package/src/types/events.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { TodoItem } from "./core
|
|
2
|
-
import type { DeepAgentState } from "./backend
|
|
1
|
+
import type { TodoItem } from "./core";
|
|
2
|
+
import type { DeepAgentState } from "./backend";
|
|
3
3
|
import type { ModelMessage } from "ai";
|
|
4
|
-
import type { ResumeOptions } from "../checkpointer/types
|
|
4
|
+
import type { ResumeOptions } from "../checkpointer/types";
|
|
5
5
|
|
|
6
6
|
// ============================================================================
|
|
7
7
|
// Event Types for Streaming
|
|
@@ -54,6 +54,7 @@ export interface ToolResultEvent {
|
|
|
54
54
|
toolName: string;
|
|
55
55
|
toolCallId: string;
|
|
56
56
|
result: unknown;
|
|
57
|
+
isError?: boolean;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
/**
|
package/src/types/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type {
|
|
|
14
14
|
AdvancedAgentOptions,
|
|
15
15
|
SummarizationConfig,
|
|
16
16
|
CreateDeepAgentParams,
|
|
17
|
-
} from "./core
|
|
17
|
+
} from "./core";
|
|
18
18
|
|
|
19
19
|
// Backend types
|
|
20
20
|
export type {
|
|
@@ -28,9 +28,9 @@ export type {
|
|
|
28
28
|
BackendFactory,
|
|
29
29
|
ExecuteResponse,
|
|
30
30
|
SandboxBackendProtocol,
|
|
31
|
-
} from "./backend
|
|
31
|
+
} from "./backend";
|
|
32
32
|
|
|
33
|
-
export { isSandboxBackend } from "./backend
|
|
33
|
+
export { isSandboxBackend } from "./backend";
|
|
34
34
|
|
|
35
35
|
// Event types
|
|
36
36
|
export type {
|
|
@@ -70,7 +70,7 @@ export type {
|
|
|
70
70
|
EventCallback,
|
|
71
71
|
ToolEventContext,
|
|
72
72
|
StreamWithEventsOptions,
|
|
73
|
-
} from "./events
|
|
73
|
+
} from "./events";
|
|
74
74
|
|
|
75
75
|
// Subagent types
|
|
76
76
|
export type {
|
|
@@ -79,16 +79,16 @@ export type {
|
|
|
79
79
|
BuiltinToolCreator,
|
|
80
80
|
SubagentToolConfig,
|
|
81
81
|
SubAgent,
|
|
82
|
-
} from "./subagent
|
|
82
|
+
} from "./subagent";
|
|
83
83
|
|
|
84
84
|
// Structured output types
|
|
85
85
|
export type {
|
|
86
86
|
StructuredAgentResult,
|
|
87
|
-
} from "./structured-output
|
|
87
|
+
} from "./structured-output";
|
|
88
88
|
|
|
89
89
|
export {
|
|
90
90
|
hasStructuredOutput,
|
|
91
91
|
eventHasStructuredOutput,
|
|
92
92
|
getStructuredOutput,
|
|
93
93
|
getEventOutput,
|
|
94
|
-
} from "./structured-output
|
|
94
|
+
} from "./structured-output";
|
package/src/types/subagent.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import type { ToolSet, LanguageModel } from "ai";
|
|
6
6
|
import type { z } from "zod";
|
|
7
|
-
import type { GenerationOptions, AdvancedAgentOptions } from "./core
|
|
7
|
+
import type { GenerationOptions, AdvancedAgentOptions } from "./core";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Configuration for dynamic tool approval.
|
package/src/utils/eviction.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* This prevents context overflow from large tool outputs.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { BackendProtocol, BackendFactory, DeepAgentState } from "../types
|
|
10
|
-
import { DEFAULT_EVICTION_TOKEN_LIMIT as CENTRALIZED_EVICTION_LIMIT } from "../constants/limits
|
|
9
|
+
import type { BackendProtocol, BackendFactory, DeepAgentState } from "../types";
|
|
10
|
+
import { DEFAULT_EVICTION_TOKEN_LIMIT as CENTRALIZED_EVICTION_LIMIT } from "../constants/limits";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Default token limit before evicting a tool result.
|
package/src/utils/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Utility functions for AI SDK Deep Agent.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export { patchToolCalls, hasDanglingToolCalls } from "./patch-tool-calls
|
|
5
|
+
export { patchToolCalls, hasDanglingToolCalls } from "./patch-tool-calls";
|
|
6
6
|
export {
|
|
7
7
|
evictToolResult,
|
|
8
8
|
createToolResultWrapper,
|
|
@@ -12,7 +12,7 @@ export {
|
|
|
12
12
|
DEFAULT_EVICTION_TOKEN_LIMIT,
|
|
13
13
|
type EvictOptions,
|
|
14
14
|
type EvictResult,
|
|
15
|
-
} from "./eviction
|
|
15
|
+
} from "./eviction";
|
|
16
16
|
export {
|
|
17
17
|
summarizeIfNeeded,
|
|
18
18
|
needsSummarization,
|
|
@@ -21,14 +21,14 @@ export {
|
|
|
21
21
|
DEFAULT_KEEP_MESSAGES,
|
|
22
22
|
type SummarizationOptions,
|
|
23
23
|
type SummarizationResult,
|
|
24
|
-
} from "./summarization
|
|
24
|
+
} from "./summarization";
|
|
25
25
|
export {
|
|
26
26
|
parseModelString,
|
|
27
|
-
} from "./model-parser
|
|
27
|
+
} from "./model-parser";
|
|
28
28
|
export {
|
|
29
29
|
applyInterruptConfig,
|
|
30
30
|
wrapToolsWithApproval,
|
|
31
31
|
hasApprovalTools,
|
|
32
32
|
type ApprovalCallback,
|
|
33
|
-
} from "./approval
|
|
33
|
+
} from "./approval";
|
|
34
34
|
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { generateText, type LanguageModel } from "ai";
|
|
9
|
-
import type { ModelMessage } from "../types
|
|
10
|
-
import { estimateTokens } from "./eviction
|
|
9
|
+
import type { ModelMessage } from "../types";
|
|
10
|
+
import { estimateTokens } from "./eviction";
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_SUMMARIZATION_THRESHOLD as CENTRALIZED_THRESHOLD,
|
|
13
13
|
DEFAULT_KEEP_MESSAGES as CENTRALIZED_KEEP,
|
|
14
|
-
} from "../constants/limits
|
|
14
|
+
} from "../constants/limits";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Default token threshold before triggering summarization.
|