@minpeter/pss-runtime 0.0.4 → 0.0.6
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 +89 -101
- package/dist/agent-loop.d.ts +20 -12
- package/dist/agent-loop.js +45 -48
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +34 -17
- package/dist/agent.js +50 -31
- package/dist/agent.js.map +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +4 -5
- package/dist/llm.d.ts +29 -23
- package/dist/llm.js +15 -11
- package/dist/llm.js.map +1 -1
- package/dist/session/events.d.ts +76 -61
- package/dist/session/history.js +32 -30
- package/dist/session/history.js.map +1 -1
- package/dist/session/mapping.js +92 -52
- package/dist/session/mapping.js.map +1 -1
- package/dist/session/run.d.ts +9 -0
- package/dist/session/run.js +78 -0
- package/dist/session/run.js.map +1 -0
- package/dist/session/session.d.ts +9 -16
- package/dist/session/session.js +193 -320
- package/dist/session/session.js.map +1 -1
- package/dist/session/snapshot.js +20 -0
- package/dist/session/snapshot.js.map +1 -0
- package/dist/session/store/file.d.ts +14 -0
- package/dist/session/store/file.js +106 -0
- package/dist/session/store/file.js.map +1 -0
- package/dist/session/store/memory.d.ts +13 -0
- package/dist/session/store/memory.js +31 -0
- package/dist/session/store/memory.js.map +1 -0
- package/dist/session/store/types.d.ts +22 -0
- package/package.json +16 -2
- package/dist/agent-loop.d.ts.map +0 -1
- package/dist/agent.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/llm.d.ts.map +0 -1
- package/dist/session/events.d.ts.map +0 -1
- package/dist/session/events.js +0 -2
- package/dist/session/events.js.map +0 -1
- package/dist/session/history.d.ts +0 -11
- package/dist/session/history.d.ts.map +0 -1
- package/dist/session/mapping.d.ts +0 -7
- package/dist/session/mapping.d.ts.map +0 -1
- package/dist/session/session.d.ts.map +0 -1
package/dist/llm.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { generateText } from "ai";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
//#region src/llm.ts
|
|
3
|
+
function createLlm({ model, instructions, tools }) {
|
|
4
|
+
return async ({ history, signal }) => {
|
|
5
|
+
const { responseMessages } = await generateText({
|
|
6
|
+
abortSignal: signal,
|
|
7
|
+
instructions,
|
|
8
|
+
messages: [...history],
|
|
9
|
+
model,
|
|
10
|
+
tools
|
|
11
|
+
});
|
|
12
|
+
return responseMessages;
|
|
13
|
+
};
|
|
13
14
|
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { createLlm };
|
|
17
|
+
|
|
14
18
|
//# sourceMappingURL=llm.js.map
|
package/dist/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","
|
|
1
|
+
{"version":3,"file":"llm.js","names":[],"sources":["../src/llm.ts"],"sourcesContent":["import type {\n LanguageModel,\n ModelMessage,\n Tool,\n ToolExecutionOptions,\n ToolSet,\n} from \"ai\";\nimport { generateText } from \"ai\";\n\nexport type AgentToolExecutionOptions = ToolExecutionOptions<unknown>;\nexport type AgentToolExecute = NonNullable<Tool[\"execute\"]>;\nexport type AgentTool = Tool;\nexport type AgentTools = ToolSet;\nexport type AgentModel = LanguageModel;\nexport type AgentMessage = ModelMessage;\nexport type LlmOutput = Awaited<\n ReturnType<typeof generateText>\n>[\"responseMessages\"];\nexport type LlmOutputPart = LlmOutput[number];\n\nexport interface LlmContext {\n history: readonly ModelMessage[];\n signal: AbortSignal;\n}\n\nexport type Llm = (context: LlmContext) => Promise<LlmOutput>;\n\nexport interface CreateLlmOptions {\n instructions?: string;\n model: LanguageModel;\n tools?: AgentTools;\n}\n\nexport type RuntimeCreateLlmOptions = CreateLlmOptions;\nexport type RuntimeLlm = Llm;\nexport type RuntimeLlmContext = LlmContext;\nexport type RuntimeLlmOutput = LlmOutput;\n\nexport function createLlm({\n model,\n instructions,\n tools,\n}: CreateLlmOptions): Llm {\n return async ({ history, signal }) => {\n const { responseMessages } = await generateText({\n abortSignal: signal,\n instructions,\n messages: [...history],\n model,\n tools,\n });\n\n return responseMessages;\n };\n}\n"],"mappings":";;AAsCA,SAAgB,UAAU,EACxB,OACA,cACA,SACwB;CACxB,OAAO,OAAO,EAAE,SAAS,aAAa;EACpC,MAAM,EAAE,qBAAqB,MAAM,aAAa;GAC9C,aAAa;GACb;GACA,UAAU,CAAC,GAAG,OAAO;GACrB;GACA;EACF,CAAC;EAED,OAAO;CACT;AACF"}
|
package/dist/session/events.d.ts
CHANGED
|
@@ -1,63 +1,78 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
1
|
+
//#region src/session/events.d.ts
|
|
2
|
+
type UserTextContent = string | readonly string[];
|
|
3
|
+
interface UserText {
|
|
4
|
+
text: UserTextContent;
|
|
5
|
+
type: "user-text";
|
|
6
|
+
}
|
|
7
|
+
interface UserMessageTextPart {
|
|
8
|
+
text: string;
|
|
9
|
+
type: "text";
|
|
10
|
+
}
|
|
11
|
+
interface UserMessageImagePart {
|
|
12
|
+
image: string;
|
|
13
|
+
mediaType?: string;
|
|
14
|
+
type: "image";
|
|
15
|
+
}
|
|
16
|
+
type UserMessageFileData = string | {
|
|
17
|
+
data: string;
|
|
18
|
+
type: "data";
|
|
19
|
+
} | {
|
|
20
|
+
reference: Record<string, string>;
|
|
21
|
+
type: "reference";
|
|
22
|
+
} | {
|
|
23
|
+
text: string;
|
|
24
|
+
type: "text";
|
|
25
|
+
} | {
|
|
26
|
+
type: "url";
|
|
27
|
+
url: string;
|
|
28
|
+
};
|
|
29
|
+
interface UserMessageFilePart {
|
|
30
|
+
data: UserMessageFileData;
|
|
31
|
+
filename?: string;
|
|
32
|
+
mediaType: string;
|
|
33
|
+
type: "file";
|
|
34
|
+
}
|
|
35
|
+
type UserMessageContentPart = UserMessageFilePart | UserMessageImagePart | UserMessageTextPart;
|
|
36
|
+
type UserMessageContent = readonly UserMessageContentPart[];
|
|
37
|
+
interface UserMessage {
|
|
38
|
+
content: UserMessageContent;
|
|
39
|
+
type: "user-message";
|
|
40
|
+
}
|
|
41
|
+
interface AssistantText {
|
|
42
|
+
text: string;
|
|
43
|
+
type: "assistant-text";
|
|
44
|
+
}
|
|
45
|
+
interface AssistantReasoning {
|
|
46
|
+
text: string;
|
|
47
|
+
type: "assistant-reasoning";
|
|
48
|
+
}
|
|
49
|
+
interface ToolCall {
|
|
50
|
+
input: unknown;
|
|
51
|
+
toolCallId: string;
|
|
52
|
+
toolName: string;
|
|
53
|
+
type: "tool-call";
|
|
54
|
+
}
|
|
55
|
+
interface ToolResult {
|
|
56
|
+
output: unknown;
|
|
57
|
+
toolCallId: string;
|
|
58
|
+
toolName: string;
|
|
59
|
+
type: "tool-result";
|
|
60
|
+
}
|
|
61
|
+
type AgentEvent = /** User input was accepted into the session queue. */UserMessage | UserText /** User multipart input was accepted into the session queue. */ | UserMessage /** A queued user input started running as a turn. */ | {
|
|
62
|
+
type: "turn-start";
|
|
63
|
+
} /** The active turn was interrupted before normal completion. */ | {
|
|
64
|
+
type: "turn-abort";
|
|
65
|
+
} /** The active turn hit an unrecoverable runtime failure. */ | {
|
|
66
|
+
type: "turn-error";
|
|
67
|
+
message: string;
|
|
68
|
+
} /** The active turn completed normally. */ | {
|
|
69
|
+
type: "turn-end";
|
|
70
|
+
} /** One model/tool-loop iteration started within the active turn. */ | {
|
|
71
|
+
type: "step-start";
|
|
72
|
+
} /** The model produced reasoning content. */ | AssistantReasoning /** The model produced visible assistant text. */ | AssistantText /** The model requested a tool call. */ | ToolCall /** A tool call returned a result. */ | ToolResult /** One model/tool-loop iteration finished within the active turn. */ | {
|
|
73
|
+
type: "step-end";
|
|
61
74
|
};
|
|
62
|
-
|
|
75
|
+
type AgentEventListener = (event: AgentEvent) => void;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { AgentEvent, AgentEventListener, AssistantReasoning, AssistantText, ToolCall, ToolResult, UserMessage, UserMessageContent, UserMessageContentPart, UserMessageFileData, UserMessageFilePart, UserMessageImagePart, UserMessageTextPart, UserText, UserTextContent };
|
|
63
78
|
//# sourceMappingURL=events.d.ts.map
|
package/dist/session/history.js
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
1
|
+
import { userInputToModelMessage } from "./mapping.js";
|
|
2
|
+
//#region src/session/history.ts
|
|
3
|
+
var AgentModelHistory = class {
|
|
4
|
+
#modelHistory = [];
|
|
5
|
+
#onChange;
|
|
6
|
+
constructor(history, onChange) {
|
|
7
|
+
if (history) this.#modelHistory = structuredClone(history);
|
|
8
|
+
this.#onChange = onChange;
|
|
9
|
+
}
|
|
10
|
+
modelSnapshot() {
|
|
11
|
+
return structuredClone(this.#modelHistory);
|
|
12
|
+
}
|
|
13
|
+
appendUserInput(input) {
|
|
14
|
+
this.#modelHistory.push(userInputToModelMessage(input));
|
|
15
|
+
this.#triggerChange();
|
|
16
|
+
}
|
|
17
|
+
appendModelMessage(message) {
|
|
18
|
+
this.#modelHistory.push(structuredClone(message));
|
|
19
|
+
this.#triggerChange();
|
|
20
|
+
}
|
|
21
|
+
rollback(snapshot) {
|
|
22
|
+
this.#modelHistory.length = 0;
|
|
23
|
+
this.#modelHistory.push(...structuredClone(snapshot));
|
|
24
|
+
this.#triggerChange();
|
|
25
|
+
}
|
|
26
|
+
#triggerChange() {
|
|
27
|
+
this.#onChange?.(this.modelSnapshot());
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { AgentModelHistory };
|
|
32
|
+
|
|
31
33
|
//# sourceMappingURL=history.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","
|
|
1
|
+
{"version":3,"file":"history.js","names":["#modelHistory","#onChange","#triggerChange"],"sources":["../../src/session/history.ts"],"sourcesContent":["import type { ModelMessage } from \"ai\";\nimport { userInputToModelMessage } from \"./mapping\";\nimport type { UserInput } from \"./session\";\n\nexport class AgentModelHistory {\n readonly #modelHistory: ModelMessage[] = [];\n readonly #onChange?: (snapshot: ModelMessage[]) => void;\n\n constructor(\n history?: ModelMessage[],\n onChange?: (snapshot: ModelMessage[]) => void\n ) {\n if (history) {\n this.#modelHistory = structuredClone(history);\n }\n this.#onChange = onChange;\n }\n\n modelSnapshot(): ModelMessage[] {\n return structuredClone(this.#modelHistory);\n }\n\n appendUserInput(input: UserInput): void {\n this.#modelHistory.push(userInputToModelMessage(input));\n this.#triggerChange();\n }\n\n appendModelMessage(message: ModelMessage): void {\n this.#modelHistory.push(structuredClone(message));\n this.#triggerChange();\n }\n\n rollback(snapshot: ModelMessage[]): void {\n this.#modelHistory.length = 0;\n this.#modelHistory.push(...structuredClone(snapshot));\n this.#triggerChange();\n }\n\n #triggerChange(): void {\n this.#onChange?.(this.modelSnapshot());\n }\n}\n"],"mappings":";;AAIA,IAAa,oBAAb,MAA+B;CAC7B,gBAAyC,CAAC;CAC1C;CAEA,YACE,SACA,UACA;EACA,IAAI,SACF,KAAKA,gBAAgB,gBAAgB,OAAO;EAE9C,KAAKC,YAAY;CACnB;CAEA,gBAAgC;EAC9B,OAAO,gBAAgB,KAAKD,aAAa;CAC3C;CAEA,gBAAgB,OAAwB;EACtC,KAAKA,cAAc,KAAK,wBAAwB,KAAK,CAAC;EACtD,KAAKE,eAAe;CACtB;CAEA,mBAAmB,SAA6B;EAC9C,KAAKF,cAAc,KAAK,gBAAgB,OAAO,CAAC;EAChD,KAAKE,eAAe;CACtB;CAEA,SAAS,UAAgC;EACvC,KAAKF,cAAc,SAAS;EAC5B,KAAKA,cAAc,KAAK,GAAG,gBAAgB,QAAQ,CAAC;EACpD,KAAKE,eAAe;CACtB;CAEA,iBAAuB;EACrB,KAAKD,YAAY,KAAK,cAAc,CAAC;CACvC;AACF"}
|
package/dist/session/mapping.js
CHANGED
|
@@ -1,67 +1,107 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
//#region src/session/mapping.ts
|
|
2
|
+
function userInputToModelMessage(input) {
|
|
3
|
+
if (input.type === "user-message") return userMessageToModelMessage(input);
|
|
4
|
+
return userTextToModelMessage(input);
|
|
5
|
+
}
|
|
6
|
+
function userTextToModelMessage(input) {
|
|
7
|
+
return {
|
|
8
|
+
role: "user",
|
|
9
|
+
content: userTextContentToUserContent(input.text)
|
|
10
|
+
};
|
|
4
11
|
}
|
|
5
12
|
function userTextContentToUserContent(text) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
13
|
+
if (typeof text === "string") return text;
|
|
14
|
+
return text.map((part) => ({
|
|
15
|
+
type: "text",
|
|
16
|
+
text: part
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
function userMessageToModelMessage(input) {
|
|
20
|
+
return {
|
|
21
|
+
role: "user",
|
|
22
|
+
content: userMessageContentToUserContent(input.content)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function userMessageContentToUserContent(content) {
|
|
26
|
+
return content.map(userMessageContentPartToUserContentPart);
|
|
27
|
+
}
|
|
28
|
+
function userMessageContentPartToUserContentPart(part) {
|
|
29
|
+
if (part.type === "text") return {
|
|
30
|
+
type: "text",
|
|
31
|
+
text: part.text
|
|
32
|
+
};
|
|
33
|
+
if (part.type === "image") return {
|
|
34
|
+
type: "file",
|
|
35
|
+
data: part.image,
|
|
36
|
+
mediaType: part.mediaType ?? "image"
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
type: "file",
|
|
40
|
+
data: userMessageFileDataToFileData(part.data),
|
|
41
|
+
mediaType: part.mediaType,
|
|
42
|
+
...part.filename === void 0 ? {} : { filename: part.filename }
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function userMessageFileDataToFileData(data) {
|
|
46
|
+
if (typeof data === "string") return data;
|
|
47
|
+
if (data.type === "url") return data.url;
|
|
48
|
+
if (data.type === "data") return {
|
|
49
|
+
type: "data",
|
|
50
|
+
data: data.data
|
|
51
|
+
};
|
|
52
|
+
if (data.type === "reference") return {
|
|
53
|
+
type: "reference",
|
|
54
|
+
reference: { ...data.reference }
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
type: "text",
|
|
58
|
+
text: data.text
|
|
59
|
+
};
|
|
10
60
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
if (message.role === "tool") {
|
|
17
|
-
return message.content.flatMap(toolContentPartToEvents);
|
|
18
|
-
}
|
|
19
|
-
return [];
|
|
61
|
+
function modelMessageToAgentEvents(message) {
|
|
62
|
+
if (message.role === "assistant") return assistantReasoningFirstParts(assistantContentParts(message)).flatMap(assistantContentPartToEvents);
|
|
63
|
+
if (message.role === "tool") return message.content.flatMap(toolContentPartToEvents);
|
|
64
|
+
return [];
|
|
20
65
|
}
|
|
21
66
|
function assistantContentParts(message) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
67
|
+
return typeof message.content === "string" ? [{
|
|
68
|
+
type: "text",
|
|
69
|
+
text: message.content
|
|
70
|
+
}] : message.content;
|
|
25
71
|
}
|
|
26
72
|
function assistantReasoningFirstParts(parts) {
|
|
27
|
-
|
|
28
|
-
...parts.filter((part) => part.type === "reasoning"),
|
|
29
|
-
...parts.filter((part) => part.type !== "reasoning"),
|
|
30
|
-
];
|
|
73
|
+
return [...parts.filter((part) => part.type === "reasoning"), ...parts.filter((part) => part.type !== "reasoning")];
|
|
31
74
|
}
|
|
32
75
|
function assistantContentPartToEvents(part) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
return [];
|
|
76
|
+
if (part.type === "text") return part.text ? [{
|
|
77
|
+
type: "assistant-text",
|
|
78
|
+
text: part.text
|
|
79
|
+
}] : [];
|
|
80
|
+
if (part.type === "reasoning") return part.text ? [{
|
|
81
|
+
type: "assistant-reasoning",
|
|
82
|
+
text: part.text
|
|
83
|
+
}] : [];
|
|
84
|
+
if (part.type === "tool-call") return [{
|
|
85
|
+
type: "tool-call",
|
|
86
|
+
input: part.input,
|
|
87
|
+
toolCallId: part.toolCallId,
|
|
88
|
+
toolName: part.toolName
|
|
89
|
+
}];
|
|
90
|
+
return [];
|
|
50
91
|
}
|
|
51
92
|
function toolContentPartToEvents(part) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
return [];
|
|
93
|
+
if (part.type === "tool-result") return toolResultPartToEvents(part);
|
|
94
|
+
return [];
|
|
56
95
|
}
|
|
57
96
|
function toolResultPartToEvents(part) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
},
|
|
65
|
-
];
|
|
97
|
+
return [{
|
|
98
|
+
type: "tool-result",
|
|
99
|
+
output: part.output,
|
|
100
|
+
toolCallId: part.toolCallId,
|
|
101
|
+
toolName: part.toolName
|
|
102
|
+
}];
|
|
66
103
|
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { modelMessageToAgentEvents, userInputToModelMessage };
|
|
106
|
+
|
|
67
107
|
//# sourceMappingURL=mapping.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.js","
|
|
1
|
+
{"version":3,"file":"mapping.js","names":[],"sources":["../../src/session/mapping.ts"],"sourcesContent":["import type {\n AssistantContent,\n AssistantModelMessage,\n ModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from \"ai\";\nimport type {\n AssistantReasoning,\n AssistantText,\n ToolCall,\n ToolResult,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserText,\n UserTextContent,\n} from \"./events\";\nimport type { UserInput } from \"./session\";\n\ntype AssistantContentPart = Exclude<AssistantContent, string>[number];\ntype ToolContentPart = ToolModelMessage[\"content\"][number];\ntype ModelEvent = AssistantReasoning | AssistantText | ToolCall | ToolResult;\n\n// UserInput -> AI SDK UserModelMessage\nexport function userInputToModelMessage(input: UserInput): UserModelMessage {\n if (input.type === \"user-message\") {\n return userMessageToModelMessage(input);\n }\n\n return userTextToModelMessage(input);\n}\n\nexport function userTextToModelMessage(input: UserText): UserModelMessage {\n return { role: \"user\", content: userTextContentToUserContent(input.text) };\n}\n\nfunction userTextContentToUserContent(\n text: UserTextContent\n): UserModelMessage[\"content\"] {\n if (typeof text === \"string\") {\n return text;\n }\n\n return text.map((part) => ({ type: \"text\", text: part }));\n}\n\nexport function userMessageToModelMessage(\n input: UserMessage\n): UserModelMessage {\n return {\n role: \"user\",\n content: userMessageContentToUserContent(input.content),\n };\n}\n\nfunction userMessageContentToUserContent(\n content: UserMessageContent\n): Exclude<UserModelMessage[\"content\"], string> {\n return content.map(userMessageContentPartToUserContentPart);\n}\n\nfunction userMessageContentPartToUserContentPart(\n part: UserMessageContentPart\n): Exclude<UserModelMessage[\"content\"], string>[number] {\n if (part.type === \"text\") {\n return { type: \"text\", text: part.text };\n }\n\n if (part.type === \"image\") {\n return {\n type: \"file\",\n data: part.image,\n mediaType: part.mediaType ?? \"image\",\n };\n }\n\n return {\n type: \"file\",\n data: userMessageFileDataToFileData(part.data),\n mediaType: part.mediaType,\n ...(part.filename === undefined ? {} : { filename: part.filename }),\n };\n}\n\nfunction userMessageFileDataToFileData(\n data: UserMessageFileData\n): Extract<\n Exclude<UserModelMessage[\"content\"], string>[number],\n { type: \"file\" }\n>[\"data\"] {\n if (typeof data === \"string\") {\n return data;\n }\n\n if (data.type === \"url\") {\n return data.url;\n }\n\n if (data.type === \"data\") {\n return { type: \"data\", data: data.data };\n }\n\n if (data.type === \"reference\") {\n return { type: \"reference\", reference: { ...data.reference } };\n }\n\n return { type: \"text\", text: data.text };\n}\n\n// AI SDK ModelMessage -> public agent events\nexport function modelMessageToAgentEvents(message: ModelMessage): ModelEvent[] {\n if (message.role === \"assistant\") {\n return assistantReasoningFirstParts(assistantContentParts(message)).flatMap(\n assistantContentPartToEvents\n );\n }\n\n if (message.role === \"tool\") {\n return message.content.flatMap(toolContentPartToEvents);\n }\n\n return [];\n}\n\nfunction assistantContentParts(\n message: AssistantModelMessage\n): AssistantContentPart[] {\n return typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content;\n}\n\nfunction assistantReasoningFirstParts(\n parts: AssistantContentPart[]\n): AssistantContentPart[] {\n return [\n ...parts.filter((part) => part.type === \"reasoning\"),\n ...parts.filter((part) => part.type !== \"reasoning\"),\n ];\n}\n\nfunction assistantContentPartToEvents(\n part: AssistantContentPart\n): ModelEvent[] {\n if (part.type === \"text\") {\n return part.text ? [{ type: \"assistant-text\", text: part.text }] : [];\n }\n\n if (part.type === \"reasoning\") {\n return part.text ? [{ type: \"assistant-reasoning\", text: part.text }] : [];\n }\n\n if (part.type === \"tool-call\") {\n return [\n {\n type: \"tool-call\",\n input: part.input,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n }\n\n return [];\n}\n\nfunction toolContentPartToEvents(part: ToolContentPart): ModelEvent[] {\n if (part.type === \"tool-result\") {\n return toolResultPartToEvents(part);\n }\n\n return [];\n}\n\nfunction toolResultPartToEvents(part: {\n output: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-result\";\n}): ModelEvent[] {\n return [\n {\n type: \"tool-result\",\n output: part.output,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n}\n"],"mappings":";AA0BA,SAAgB,wBAAwB,OAAoC;CAC1E,IAAI,MAAM,SAAS,gBACjB,OAAO,0BAA0B,KAAK;CAGxC,OAAO,uBAAuB,KAAK;AACrC;AAEA,SAAgB,uBAAuB,OAAmC;CACxE,OAAO;EAAE,MAAM;EAAQ,SAAS,6BAA6B,MAAM,IAAI;CAAE;AAC3E;AAEA,SAAS,6BACP,MAC6B;CAC7B,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,OAAO,KAAK,KAAK,UAAU;EAAE,MAAM;EAAQ,MAAM;CAAK,EAAE;AAC1D;AAEA,SAAgB,0BACd,OACkB;CAClB,OAAO;EACL,MAAM;EACN,SAAS,gCAAgC,MAAM,OAAO;CACxD;AACF;AAEA,SAAS,gCACP,SAC8C;CAC9C,OAAO,QAAQ,IAAI,uCAAuC;AAC5D;AAEA,SAAS,wCACP,MACsD;CACtD,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,SAChB,OAAO;EACL,MAAM;EACN,MAAM,KAAK;EACX,WAAW,KAAK,aAAa;CAC/B;CAGF,OAAO;EACL,MAAM;EACN,MAAM,8BAA8B,KAAK,IAAI;EAC7C,WAAW,KAAK;EAChB,GAAI,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;CACnE;AACF;AAEA,SAAS,8BACP,MAIQ;CACR,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,KAAK,SAAS,OAChB,OAAO,KAAK;CAGd,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,aAChB,OAAO;EAAE,MAAM;EAAa,WAAW,EAAE,GAAG,KAAK,UAAU;CAAE;CAG/D,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;AACzC;AAGA,SAAgB,0BAA0B,SAAqC;CAC7E,IAAI,QAAQ,SAAS,aACnB,OAAO,6BAA6B,sBAAsB,OAAO,CAAC,EAAE,QAClE,4BACF;CAGF,IAAI,QAAQ,SAAS,QACnB,OAAO,QAAQ,QAAQ,QAAQ,uBAAuB;CAGxD,OAAO,CAAC;AACV;AAEA,SAAS,sBACP,SACwB;CACxB,OAAO,OAAO,QAAQ,YAAY,WAC9B,CAAC;EAAE,MAAM;EAAQ,MAAM,QAAQ;CAAQ,CAAC,IACxC,QAAQ;AACd;AAEA,SAAS,6BACP,OACwB;CACxB,OAAO,CACL,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,GACnD,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,CACrD;AACF;AAEA,SAAS,6BACP,MACc;CACd,IAAI,KAAK,SAAS,QAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAkB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAGtE,IAAI,KAAK,SAAS,aAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAuB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAG3E,IAAI,KAAK,SAAS,aAChB,OAAO,CACL;EACE,MAAM;EACN,OAAO,KAAK;EACZ,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;CAGF,OAAO,CAAC;AACV;AAEA,SAAS,wBAAwB,MAAqC;CACpE,IAAI,KAAK,SAAS,eAChB,OAAO,uBAAuB,IAAI;CAGpC,OAAO,CAAC;AACV;AAEA,SAAS,uBAAuB,MAKf;CACf,OAAO,CACL;EACE,MAAM;EACN,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;AACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/session/run.ts
|
|
2
|
+
var BufferedAgentRun = class {
|
|
3
|
+
#events = [];
|
|
4
|
+
#waiters = [];
|
|
5
|
+
#closed = false;
|
|
6
|
+
#error;
|
|
7
|
+
#streamStarted = false;
|
|
8
|
+
emit(event) {
|
|
9
|
+
if (this.#closed) return;
|
|
10
|
+
const waiter = this.#waiters.shift();
|
|
11
|
+
if (waiter) {
|
|
12
|
+
waiter.resolve({
|
|
13
|
+
done: false,
|
|
14
|
+
value: event
|
|
15
|
+
});
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.#events.push(structuredClone(event));
|
|
19
|
+
}
|
|
20
|
+
close(error) {
|
|
21
|
+
if (this.#closed) return;
|
|
22
|
+
this.#closed = true;
|
|
23
|
+
this.#error = error;
|
|
24
|
+
while (this.#waiters.length > 0) {
|
|
25
|
+
const waiter = this.#waiters.shift();
|
|
26
|
+
if (!waiter) continue;
|
|
27
|
+
if (error) waiter.reject(error);
|
|
28
|
+
else waiter.resolve({
|
|
29
|
+
done: true,
|
|
30
|
+
value: void 0
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
stream() {
|
|
35
|
+
if (this.#streamStarted) throw new Error("AgentRun.stream() can only be consumed once");
|
|
36
|
+
this.#streamStarted = true;
|
|
37
|
+
const iterator = {
|
|
38
|
+
next: () => this.#next(),
|
|
39
|
+
return: () => {
|
|
40
|
+
this.#cancel();
|
|
41
|
+
return Promise.resolve({
|
|
42
|
+
done: true,
|
|
43
|
+
value: void 0
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
[Symbol.asyncIterator]: () => iterator
|
|
47
|
+
};
|
|
48
|
+
return iterator;
|
|
49
|
+
}
|
|
50
|
+
#cancel() {
|
|
51
|
+
this.#events.length = 0;
|
|
52
|
+
this.close();
|
|
53
|
+
}
|
|
54
|
+
#next() {
|
|
55
|
+
const event = this.#events.shift();
|
|
56
|
+
if (event) return Promise.resolve({
|
|
57
|
+
done: false,
|
|
58
|
+
value: event
|
|
59
|
+
});
|
|
60
|
+
if (this.#closed) {
|
|
61
|
+
if (this.#error) return Promise.reject(this.#error);
|
|
62
|
+
return Promise.resolve({
|
|
63
|
+
done: true,
|
|
64
|
+
value: void 0
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
this.#waiters.push({
|
|
69
|
+
reject,
|
|
70
|
+
resolve
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { BufferedAgentRun };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","names":["#events","#waiters","#closed","#error","#streamStarted","#next","#cancel"],"sources":["../../src/session/run.ts"],"sourcesContent":["import type { AgentEvent } from \"./events\";\n\nexport interface AgentRun {\n stream(): AsyncIterable<AgentEvent>;\n}\n\nexport class BufferedAgentRun implements AgentRun {\n readonly #events: AgentEvent[] = [];\n readonly #waiters: Array<{\n reject: (error: unknown) => void;\n resolve: (value: IteratorResult<AgentEvent>) => void;\n }> = [];\n #closed = false;\n #error: unknown;\n #streamStarted = false;\n\n emit(event: AgentEvent): void {\n if (this.#closed) {\n return;\n }\n\n const waiter = this.#waiters.shift();\n if (waiter) {\n waiter.resolve({ done: false, value: event });\n return;\n }\n\n this.#events.push(structuredClone(event));\n }\n\n close(error?: unknown): void {\n if (this.#closed) {\n return;\n }\n\n this.#closed = true;\n this.#error = error;\n\n while (this.#waiters.length > 0) {\n const waiter = this.#waiters.shift();\n if (!waiter) {\n continue;\n }\n\n if (error) {\n waiter.reject(error);\n } else {\n waiter.resolve({ done: true, value: undefined });\n }\n }\n }\n\n stream(): AsyncIterable<AgentEvent> {\n if (this.#streamStarted) {\n throw new Error(\"AgentRun.stream() can only be consumed once\");\n }\n this.#streamStarted = true;\n\n const iterator: AsyncIterableIterator<AgentEvent> = {\n next: () => this.#next(),\n return: () => {\n this.#cancel();\n return Promise.resolve({ done: true, value: undefined });\n },\n [Symbol.asyncIterator]: () => iterator,\n };\n return iterator;\n }\n\n #cancel(): void {\n this.#events.length = 0;\n this.close();\n }\n\n #next(): Promise<IteratorResult<AgentEvent>> {\n const event = this.#events.shift();\n if (event) {\n return Promise.resolve({ done: false, value: event });\n }\n\n if (this.#closed) {\n if (this.#error) {\n return Promise.reject(this.#error);\n }\n return Promise.resolve({ done: true, value: undefined });\n }\n\n return new Promise((resolve, reject) => {\n this.#waiters.push({ reject, resolve });\n });\n }\n}\n"],"mappings":";AAMA,IAAa,mBAAb,MAAkD;CAChD,UAAiC,CAAC;CAClC,WAGK,CAAC;CACN,UAAU;CACV;CACA,iBAAiB;CAEjB,KAAK,OAAyB;EAC5B,IAAI,KAAKE,SACP;EAGF,MAAM,SAAS,KAAKD,SAAS,MAAM;EACnC,IAAI,QAAQ;GACV,OAAO,QAAQ;IAAE,MAAM;IAAO,OAAO;GAAM,CAAC;GAC5C;EACF;EAEA,KAAKD,QAAQ,KAAK,gBAAgB,KAAK,CAAC;CAC1C;CAEA,MAAM,OAAuB;EAC3B,IAAI,KAAKE,SACP;EAGF,KAAKA,UAAU;EACf,KAAKC,SAAS;EAEd,OAAO,KAAKF,SAAS,SAAS,GAAG;GAC/B,MAAM,SAAS,KAAKA,SAAS,MAAM;GACnC,IAAI,CAAC,QACH;GAGF,IAAI,OACF,OAAO,OAAO,KAAK;QAEnB,OAAO,QAAQ;IAAE,MAAM;IAAM,OAAO,KAAA;GAAU,CAAC;EAEnD;CACF;CAEA,SAAoC;EAClC,IAAI,KAAKG,gBACP,MAAM,IAAI,MAAM,6CAA6C;EAE/D,KAAKA,iBAAiB;EAEtB,MAAM,WAA8C;GAClD,YAAY,KAAKC,MAAM;GACvB,cAAc;IACZ,KAAKC,QAAQ;IACb,OAAO,QAAQ,QAAQ;KAAE,MAAM;KAAM,OAAO,KAAA;IAAU,CAAC;GACzD;IACC,OAAO,sBAAsB;EAChC;EACA,OAAO;CACT;CAEA,UAAgB;EACd,KAAKN,QAAQ,SAAS;EACtB,KAAK,MAAM;CACb;CAEA,QAA6C;EAC3C,MAAM,QAAQ,KAAKA,QAAQ,MAAM;EACjC,IAAI,OACF,OAAO,QAAQ,QAAQ;GAAE,MAAM;GAAO,OAAO;EAAM,CAAC;EAGtD,IAAI,KAAKE,SAAS;GAChB,IAAI,KAAKC,QACP,OAAO,QAAQ,OAAO,KAAKA,MAAM;GAEnC,OAAO,QAAQ,QAAQ;IAAE,MAAM;IAAM,OAAO,KAAA;GAAU,CAAC;EACzD;EAEA,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAKF,SAAS,KAAK;IAAE;IAAQ;GAAQ,CAAC;EACxC,CAAC;CACH;AACF"}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
constructor(llm: Llm, options?: SessionOptions);
|
|
11
|
-
getHistory(): AgentMessage[];
|
|
12
|
-
subscribe(listener: AgentEventListener): () => void;
|
|
13
|
-
submit(input: SessionInput): Promise<void>;
|
|
14
|
-
interrupt(): void;
|
|
15
|
-
kill(): void;
|
|
16
|
-
}
|
|
1
|
+
import { UserMessage, UserMessageContentPart, UserText } from "./events.js";
|
|
2
|
+
import { AgentRun } from "./run.js";
|
|
3
|
+
|
|
4
|
+
//#region src/session/session.d.ts
|
|
5
|
+
type UserInput = UserMessage | UserText;
|
|
6
|
+
type AgentInput = readonly string[] | readonly UserMessageContentPart[] | string | UserInput;
|
|
7
|
+
type SessionInput = AgentInput;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { AgentInput, SessionInput, UserInput };
|
|
17
10
|
//# sourceMappingURL=session.d.ts.map
|