@agentica/core 0.23.0 → 0.25.0

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.
Files changed (191) hide show
  1. package/README.md +1 -1
  2. package/lib/Agentica.d.ts +7 -2
  3. package/lib/Agentica.js +12 -7
  4. package/lib/Agentica.js.map +1 -1
  5. package/lib/MicroAgentica.d.ts +2 -2
  6. package/lib/MicroAgentica.js +4 -4
  7. package/lib/MicroAgentica.js.map +1 -1
  8. package/lib/context/AgenticaContext.d.ts +6 -2
  9. package/lib/context/MicroAgenticaContext.d.ts +2 -2
  10. package/lib/context/index.d.ts +5 -0
  11. package/lib/{structures/mcp → context}/index.js +5 -1
  12. package/lib/context/index.js.map +1 -0
  13. package/lib/events/AgenticaAssistantMessageEvent.d.ts +9 -0
  14. package/lib/{histories/AgenticaUserInputHistory.js → events/AgenticaAssistantMessageEvent.js} +1 -1
  15. package/lib/events/AgenticaAssistantMessageEvent.js.map +1 -0
  16. package/lib/events/AgenticaEvent.d.ts +9 -9
  17. package/lib/events/AgenticaUserMessageEvent.d.ts +9 -0
  18. package/lib/events/{AgenticaUserInputEvent.js → AgenticaUserMessageEvent.js} +1 -1
  19. package/lib/events/AgenticaUserMessageEvent.js.map +1 -0
  20. package/lib/events/MicroAgenticaEvent.d.ts +6 -6
  21. package/lib/events/index.d.ts +14 -0
  22. package/lib/events/index.js +31 -0
  23. package/lib/events/index.js.map +1 -0
  24. package/lib/factory/events.d.ts +8 -8
  25. package/lib/factory/events.js +23 -38
  26. package/lib/factory/events.js.map +1 -1
  27. package/lib/factory/histories.d.ts +1 -36
  28. package/lib/factory/histories.js +77 -24
  29. package/lib/factory/histories.js.map +1 -1
  30. package/lib/functional/assertHttpController.js +6 -6
  31. package/lib/functional/assertHttpLlmApplication.js +6 -6
  32. package/lib/functional/assertMcpController.d.ts +1 -2
  33. package/lib/functional/assertMcpController.js +6 -6
  34. package/lib/functional/assertMcpController.js.map +1 -1
  35. package/lib/functional/index.d.ts +6 -0
  36. package/lib/functional/index.js +23 -0
  37. package/lib/functional/index.js.map +1 -0
  38. package/lib/functional/validateHttpController.js +5 -5
  39. package/lib/functional/validateHttpLlmApplication.js +5 -5
  40. package/lib/functional/validateMcpController.d.ts +1 -2
  41. package/lib/functional/validateMcpController.js +11 -11
  42. package/lib/functional/validateMcpController.js.map +1 -1
  43. package/lib/histories/{AgenticaTextHistory.d.ts → AgenticaAssistantMessageHistory.d.ts} +1 -2
  44. package/lib/histories/AgenticaAssistantMessageHistory.js +3 -0
  45. package/lib/histories/AgenticaAssistantMessageHistory.js.map +1 -0
  46. package/lib/histories/AgenticaHistory.d.ts +7 -7
  47. package/lib/histories/AgenticaUserMessageHistory.d.ts +6 -0
  48. package/lib/{events/AgenticaTextEvent.js → histories/AgenticaUserMessageHistory.js} +1 -1
  49. package/lib/histories/AgenticaUserMessageHistory.js.map +1 -0
  50. package/lib/histories/MicroAgenticaHistory.d.ts +5 -4
  51. package/lib/histories/contents/AgenticaUserMessageAudioContent.d.ts +19 -0
  52. package/lib/histories/contents/AgenticaUserMessageAudioContent.js +3 -0
  53. package/lib/histories/contents/AgenticaUserMessageAudioContent.js.map +1 -0
  54. package/lib/histories/contents/AgenticaUserMessageContent.d.ts +14 -0
  55. package/lib/histories/{AgenticaTextHistory.js → contents/AgenticaUserMessageContent.js} +1 -1
  56. package/lib/histories/contents/AgenticaUserMessageContent.js.map +1 -0
  57. package/lib/histories/contents/AgenticaUserMessageContentBase.d.ts +6 -0
  58. package/lib/histories/contents/AgenticaUserMessageContentBase.js +3 -0
  59. package/lib/histories/contents/AgenticaUserMessageContentBase.js.map +1 -0
  60. package/lib/histories/contents/AgenticaUserMessageFileContent.d.ts +26 -0
  61. package/lib/histories/contents/AgenticaUserMessageFileContent.js +3 -0
  62. package/lib/histories/contents/AgenticaUserMessageFileContent.js.map +1 -0
  63. package/lib/histories/contents/AgenticaUserMessageImageContent.d.ts +20 -0
  64. package/lib/histories/contents/AgenticaUserMessageImageContent.js +3 -0
  65. package/lib/histories/contents/AgenticaUserMessageImageContent.js.map +1 -0
  66. package/lib/histories/contents/AgenticaUserMessageTextContent.d.ts +14 -0
  67. package/lib/histories/contents/AgenticaUserMessageTextContent.js +3 -0
  68. package/lib/histories/contents/AgenticaUserMessageTextContent.js.map +1 -0
  69. package/lib/histories/contents/index.d.ts +5 -0
  70. package/lib/histories/contents/index.js +22 -0
  71. package/lib/histories/contents/index.js.map +1 -0
  72. package/lib/histories/index.d.ts +9 -0
  73. package/lib/histories/index.js +26 -0
  74. package/lib/histories/index.js.map +1 -0
  75. package/lib/index.d.ts +6 -45
  76. package/lib/index.js +6 -46
  77. package/lib/index.js.map +1 -1
  78. package/lib/index.mjs +155 -135
  79. package/lib/index.mjs.map +1 -1
  80. package/lib/json/IAgenticaEventJson.d.ts +29 -23
  81. package/lib/json/IAgenticaHistoryJson.d.ts +24 -19
  82. package/lib/json/IMicroAgenticaEventJson.d.ts +1 -1
  83. package/lib/json/IMicroAgenticaHistoryJson.d.ts +1 -1
  84. package/lib/json/index.d.ts +7 -0
  85. package/lib/json/index.js +24 -0
  86. package/lib/json/index.js.map +1 -0
  87. package/lib/orchestrate/call.js +4 -4
  88. package/lib/orchestrate/call.js.map +1 -1
  89. package/lib/orchestrate/cancel.js +1 -1
  90. package/lib/orchestrate/cancel.js.map +1 -1
  91. package/lib/orchestrate/initialize.js +4 -4
  92. package/lib/orchestrate/initialize.js.map +1 -1
  93. package/lib/orchestrate/select.js +3 -3
  94. package/lib/orchestrate/select.js.map +1 -1
  95. package/lib/structures/IAgenticaController.d.ts +1 -2
  96. package/lib/structures/index.d.ts +10 -0
  97. package/lib/structures/index.js +27 -0
  98. package/lib/structures/index.js.map +1 -0
  99. package/lib/transformers/transformEvent.d.ts +1 -0
  100. package/lib/transformers/{AgenticaEventTransformer.js → transformEvent.js} +74 -31
  101. package/lib/transformers/transformEvent.js.map +1 -0
  102. package/lib/transformers/transformHistory.d.ts +1 -0
  103. package/lib/transformers/{AgenticaHistoryTransformer.js → transformHistory.js} +24 -23
  104. package/lib/transformers/transformHistory.js.map +1 -0
  105. package/lib/utils/ChatGptCompletionMessageUtil.js +2 -2
  106. package/lib/utils/ChatGptCompletionMessageUtil.spec.d.ts +1 -0
  107. package/lib/utils/ChatGptCompletionMessageUtil.spec.js +288 -0
  108. package/lib/utils/ChatGptCompletionMessageUtil.spec.js.map +1 -0
  109. package/lib/utils/ChatGptTokenUsageAggregator.spec.d.ts +1 -0
  110. package/lib/utils/ChatGptTokenUsageAggregator.spec.js +199 -0
  111. package/lib/utils/ChatGptTokenUsageAggregator.spec.js.map +1 -0
  112. package/lib/utils/Singleton.js +18 -0
  113. package/lib/utils/Singleton.js.map +1 -1
  114. package/lib/utils/Singleton.spec.d.ts +1 -0
  115. package/lib/utils/Singleton.spec.js +106 -0
  116. package/lib/utils/Singleton.spec.js.map +1 -0
  117. package/lib/utils/__map_take.spec.d.ts +1 -0
  118. package/lib/utils/__map_take.spec.js +108 -0
  119. package/lib/utils/__map_take.spec.js.map +1 -0
  120. package/package.json +5 -6
  121. package/src/Agentica.ts +25 -10
  122. package/src/MicroAgentica.ts +12 -9
  123. package/src/context/AgenticaContext.ts +7 -2
  124. package/src/context/MicroAgenticaContext.ts +2 -2
  125. package/src/context/index.ts +5 -0
  126. package/src/events/AgenticaAssistantMessageEvent.ts +12 -0
  127. package/src/events/AgenticaEvent.ts +15 -15
  128. package/src/events/AgenticaUserMessageEvent.ts +12 -0
  129. package/src/events/MicroAgenticaEvent.ts +9 -9
  130. package/src/events/index.ts +14 -0
  131. package/src/factory/events.ts +29 -34
  132. package/src/factory/histories.ts +81 -32
  133. package/src/functional/assertMcpController.ts +4 -2
  134. package/src/functional/index.ts +7 -0
  135. package/src/functional/validateMcpController.ts +4 -2
  136. package/src/histories/{AgenticaTextHistory.ts → AgenticaAssistantMessageHistory.ts} +4 -2
  137. package/src/histories/AgenticaHistory.ts +8 -8
  138. package/src/histories/AgenticaUserMessageHistory.ts +11 -0
  139. package/src/histories/MicroAgenticaHistory.ts +6 -5
  140. package/src/histories/contents/AgenticaUserMessageAudioContent.ts +21 -0
  141. package/src/histories/contents/AgenticaUserMessageContent.ts +19 -0
  142. package/src/histories/contents/AgenticaUserMessageContentBase.ts +6 -0
  143. package/src/histories/contents/AgenticaUserMessageFileContent.ts +27 -0
  144. package/src/histories/contents/AgenticaUserMessageImageContent.ts +23 -0
  145. package/src/histories/contents/AgenticaUserMessageTextContent.ts +15 -0
  146. package/src/histories/contents/index.ts +5 -0
  147. package/src/histories/index.ts +9 -0
  148. package/src/index.ts +6 -54
  149. package/src/json/IAgenticaEventJson.ts +36 -28
  150. package/src/json/IAgenticaHistoryJson.ts +28 -22
  151. package/src/json/IMicroAgenticaEventJson.ts +2 -1
  152. package/src/json/IMicroAgenticaHistoryJson.ts +2 -1
  153. package/src/json/index.ts +7 -0
  154. package/src/orchestrate/call.ts +8 -8
  155. package/src/orchestrate/cancel.ts +2 -2
  156. package/src/orchestrate/initialize.ts +5 -5
  157. package/src/orchestrate/select.ts +5 -5
  158. package/src/structures/IAgenticaController.ts +4 -2
  159. package/src/structures/index.ts +10 -0
  160. package/src/transformers/{AgenticaEventTransformer.ts → transformEvent.ts} +94 -42
  161. package/src/transformers/{AgenticaHistoryTransformer.ts → transformHistory.ts} +30 -26
  162. package/src/utils/ChatGptCompletionMessageUtil.spec.ts +320 -0
  163. package/src/utils/ChatGptTokenUsageAggregator.spec.ts +226 -0
  164. package/src/utils/Singleton.spec.ts +138 -0
  165. package/src/utils/Singleton.ts +18 -0
  166. package/src/utils/__map_take.spec.ts +140 -0
  167. package/lib/events/AgenticaTextEvent.d.ts +0 -10
  168. package/lib/events/AgenticaTextEvent.js.map +0 -1
  169. package/lib/events/AgenticaUserInputEvent.d.ts +0 -10
  170. package/lib/events/AgenticaUserInputEvent.js.map +0 -1
  171. package/lib/histories/AgenticaTextHistory.js.map +0 -1
  172. package/lib/histories/AgenticaUserInputHistory.d.ts +0 -80
  173. package/lib/histories/AgenticaUserInputHistory.js.map +0 -1
  174. package/lib/structures/mcp/IMcpLlmTransportProps.d.ts +0 -11
  175. package/lib/structures/mcp/IMcpLlmTransportProps.js +0 -3
  176. package/lib/structures/mcp/IMcpLlmTransportProps.js.map +0 -1
  177. package/lib/structures/mcp/index.d.ts +0 -1
  178. package/lib/structures/mcp/index.js.map +0 -1
  179. package/lib/transformers/AgenticaEventTransformer.d.ts +0 -63
  180. package/lib/transformers/AgenticaEventTransformer.js.map +0 -1
  181. package/lib/transformers/AgenticaHistoryTransformer.d.ts +0 -41
  182. package/lib/transformers/AgenticaHistoryTransformer.js.map +0 -1
  183. package/lib/utils/MathUtil.d.ts +0 -3
  184. package/lib/utils/MathUtil.js +0 -8
  185. package/lib/utils/MathUtil.js.map +0 -1
  186. package/src/events/AgenticaTextEvent.ts +0 -12
  187. package/src/events/AgenticaUserInputEvent.ts +0 -12
  188. package/src/histories/AgenticaUserInputHistory.ts +0 -88
  189. package/src/structures/mcp/IMcpLlmTransportProps.ts +0 -13
  190. package/src/structures/mcp/index.ts +0 -1
  191. package/src/utils/MathUtil.ts +0 -3
@@ -1,4 +1,3 @@
1
- import type { Client } from "@modelcontextprotocol/sdk/client/index.d.ts";
2
1
  import type {
3
2
  IHttpConnection,
4
3
  IHttpLlmApplication,
@@ -126,7 +125,10 @@ export namespace IAgenticaController {
126
125
  /**
127
126
  * MCP client for connection.
128
127
  */
129
- client: Client;
128
+ // @ts-ignore Type checking only when `@modelcontextprotocol/sdk` is installed.
129
+ // This strategy is useful for someone who does not need MCP,
130
+ // for someone who has not installed `@modelcontextprotocol/sdk`.
131
+ client: import("@modelcontextprotocol/sdk/client/index.d.ts").Client;
130
132
  }
131
133
 
132
134
  interface IBase<Protocol, Application> {
@@ -0,0 +1,10 @@
1
+ export * from "./IAgenticaConfig";
2
+ export * from "./IAgenticaController";
3
+ export * from "./IAgenticaExecutor";
4
+ export * from "./IAgenticaProps";
5
+ export * from "./IAgenticaSystemPrompt";
6
+ export * from "./IAgenticaVendor";
7
+ export * from "./IMicroAgenticaConfig";
8
+ export * from "./IMicroAgenticaExecutor";
9
+ export * from "./IMicroAgenticaProps";
10
+ export * from "./IMicroAgenticaSystemPrompt";
@@ -1,6 +1,8 @@
1
1
  import type { ILlmSchema } from "@samchon/openapi";
2
2
 
3
3
  import type { AgenticaOperation } from "../context/AgenticaOperation";
4
+ import type { AgenticaUserMessageEvent, AgenticaValidateEvent } from "../events";
5
+ import type { AgenticaAssistantMessageEvent } from "../events/AgenticaAssistantMessageEvent";
4
6
  import type { AgenticaCallEvent } from "../events/AgenticaCallEvent";
5
7
  import type { AgenticaCancelEvent } from "../events/AgenticaCancelEvent";
6
8
  import type { AgenticaDescribeEvent } from "../events/AgenticaDescribeEvent";
@@ -9,32 +11,16 @@ import type { AgenticaExecuteEvent } from "../events/AgenticaExecuteEvent";
9
11
  import type { AgenticaInitializeEvent } from "../events/AgenticaInitializeEvent";
10
12
  import type { AgenticaRequestEvent } from "../events/AgenticaRequestEvent";
11
13
  import type { AgenticaSelectEvent } from "../events/AgenticaSelectEvent";
12
- import type { AgenticaTextEvent } from "../events/AgenticaTextEvent";
13
14
  import type { IAgenticaEventJson } from "../json/IAgenticaEventJson";
14
15
 
15
- import { createCallEvent, createCancelEvent, createDescribeEvent, createExecuteEvent, createInitializeEvent, createRequestEvent, createSelectEvent, createTextEvent } from "../factory/events";
16
+ import { creatAssistantEvent, createCallEvent, createCancelEvent, createDescribeEvent, createExecuteEvent, createInitializeEvent, createRequestEvent, createSelectEvent, createUserMessageEvent, createValidateEvent } from "../factory/events";
16
17
  import { createOperationSelection } from "../factory/operations";
17
18
  import { toAsyncGenerator } from "../utils/StreamUtil";
18
19
 
19
- function findOperation<Model extends ILlmSchema.Model>(props: {
20
- operations: Map<string, Map<string, AgenticaOperation<Model>>>;
21
- input: {
22
- controller: string;
23
- function: string;
24
- };
25
- }): AgenticaOperation<Model> {
26
- const found: AgenticaOperation<Model> | undefined = props.operations
27
- .get(props.input.controller)
28
- ?.get(props.input.function);
29
- if (found === undefined) {
30
- throw new Error(
31
- `No operation found: (controller: ${props.input.controller}, function: ${props.input.function})`,
32
- );
33
- }
34
- return found;
35
- }
36
-
37
- function transform<Model extends ILlmSchema.Model>(props: {
20
+ /**
21
+ * @internal
22
+ */
23
+ export function transformEvent<Model extends ILlmSchema.Model>(props: {
38
24
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
39
25
  event: IAgenticaEventJson;
40
26
  }): AgenticaEvent<Model> {
@@ -76,15 +62,26 @@ function transform<Model extends ILlmSchema.Model>(props: {
76
62
  event: props.event,
77
63
  });
78
64
  }
79
- else if (props.event.type === "text") {
80
- return transformText({
65
+ else if (props.event.type === "assistantMessage") {
66
+ return transformAssistantMessage({
67
+ event: props.event,
68
+ });
69
+ }
70
+ else if (props.event.type === "userMessage") {
71
+ return transformUserMessage({
81
72
  event: props.event,
82
73
  });
83
74
  }
84
- else { throw new Error("Unknown event type"); }
75
+ return transformValidateEvent({
76
+ operations: props.operations,
77
+ event: props.event,
78
+ });
85
79
  }
86
80
 
87
- function transformCall<Model extends ILlmSchema.Model>(props: {
81
+ /**
82
+ * @internal
83
+ */
84
+ export function transformCall<Model extends ILlmSchema.Model>(props: {
88
85
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
89
86
  event: IAgenticaEventJson.ICall;
90
87
  }): AgenticaCallEvent<Model> {
@@ -98,7 +95,10 @@ function transformCall<Model extends ILlmSchema.Model>(props: {
98
95
  });
99
96
  }
100
97
 
101
- export function transformCancel<Model extends ILlmSchema.Model>(props: {
98
+ /**
99
+ * @internal
100
+ */
101
+ function transformCancel<Model extends ILlmSchema.Model>(props: {
102
102
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
103
103
  event: IAgenticaEventJson.ICancel;
104
104
  }): AgenticaCancelEvent<Model> {
@@ -113,6 +113,9 @@ export function transformCancel<Model extends ILlmSchema.Model>(props: {
113
113
  });
114
114
  }
115
115
 
116
+ /**
117
+ * @internal
118
+ */
116
119
  function transformDescribe<Model extends ILlmSchema.Model>(props: {
117
120
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
118
121
  event: IAgenticaEventJson.IDescribe;
@@ -131,6 +134,9 @@ function transformDescribe<Model extends ILlmSchema.Model>(props: {
131
134
  });
132
135
  }
133
136
 
137
+ /**
138
+ * @internal
139
+ */
134
140
  function transformExecute<Model extends ILlmSchema.Model>(props: {
135
141
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
136
142
  event: IAgenticaEventJson.IExecute;
@@ -146,16 +152,25 @@ function transformExecute<Model extends ILlmSchema.Model>(props: {
146
152
  });
147
153
  }
148
154
 
155
+ /**
156
+ * @internal
157
+ */
149
158
  function transformInitialize(): AgenticaInitializeEvent {
150
159
  return createInitializeEvent();
151
160
  }
152
161
 
162
+ /**
163
+ * @internal
164
+ */
153
165
  function transformRequest(props: {
154
166
  event: IAgenticaEventJson.IRequest;
155
167
  }): AgenticaRequestEvent {
156
168
  return createRequestEvent(props.event);
157
169
  }
158
170
 
171
+ /**
172
+ * @internal
173
+ */
159
174
  function transformSelect<Model extends ILlmSchema.Model>(props: {
160
175
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
161
176
  event: IAgenticaEventJson.ISelect;
@@ -171,10 +186,13 @@ function transformSelect<Model extends ILlmSchema.Model>(props: {
171
186
  });
172
187
  }
173
188
 
174
- function transformText(props: {
175
- event: IAgenticaEventJson.IText;
176
- }): AgenticaTextEvent {
177
- return createTextEvent({
189
+ /**
190
+ * @internal
191
+ */
192
+ function transformAssistantMessage(props: {
193
+ event: IAgenticaEventJson.IAssistantMessage;
194
+ }): AgenticaAssistantMessageEvent {
195
+ return creatAssistantEvent({
178
196
  stream: toAsyncGenerator(props.event.text),
179
197
  done: () => true,
180
198
  get: () => props.event.text,
@@ -182,15 +200,49 @@ function transformText(props: {
182
200
  });
183
201
  }
184
202
 
185
- export const AgenticaEventTransformer = {
186
- transform,
187
- transformCall,
188
- transformCancel,
189
- transformDescribe,
190
- transformExecute,
191
- transformInitialize,
192
- transformRequest,
193
- transformSelect,
194
- transformText,
195
- findOperation,
196
- };
203
+ /**
204
+ * @internal
205
+ */
206
+ function transformUserMessage(props: {
207
+ event: IAgenticaEventJson.IUserMessage;
208
+ }): AgenticaUserMessageEvent {
209
+ return createUserMessageEvent(props.event);
210
+ }
211
+
212
+ /**
213
+ * @internal
214
+ */
215
+ function transformValidateEvent<Model extends ILlmSchema.Model>(props: {
216
+ event: IAgenticaEventJson.IValidate;
217
+ operations: Map<string, Map<string, AgenticaOperation<Model>>>;
218
+ }): AgenticaValidateEvent<Model> {
219
+ return createValidateEvent({
220
+ id: props.event.id,
221
+ operation: findOperation({
222
+ operations: props.operations,
223
+ input: props.event.operation,
224
+ }),
225
+ result: props.event.result,
226
+ });
227
+ }
228
+
229
+ /**
230
+ * @internal
231
+ */
232
+ function findOperation<Model extends ILlmSchema.Model>(props: {
233
+ operations: Map<string, Map<string, AgenticaOperation<Model>>>;
234
+ input: {
235
+ controller: string;
236
+ function: string;
237
+ };
238
+ }): AgenticaOperation<Model> {
239
+ const found: AgenticaOperation<Model> | undefined = props.operations
240
+ .get(props.input.controller)
241
+ ?.get(props.input.function);
242
+ if (found === undefined) {
243
+ throw new Error(
244
+ `No operation found: (controller: ${props.input.controller}, function: ${props.input.function})`,
245
+ );
246
+ }
247
+ return found;
248
+ }
@@ -1,24 +1,34 @@
1
1
  import type { ILlmSchema } from "@samchon/openapi";
2
2
 
3
3
  import type { AgenticaOperation } from "../context/AgenticaOperation";
4
+ import type { AgenticaUserMessageHistory } from "../histories";
5
+ import type { AgenticaAssistantMessageHistory } from "../histories/AgenticaAssistantMessageHistory";
4
6
  import type { AgenticaCancelHistory } from "../histories/AgenticaCancelHistory";
5
7
  import type { AgenticaDescribeHistory } from "../histories/AgenticaDescribeHistory";
6
8
  import type { AgenticaExecuteHistory } from "../histories/AgenticaExecuteHistory";
7
9
  import type { AgenticaHistory } from "../histories/AgenticaHistory";
8
10
  import type { AgenticaSelectHistory } from "../histories/AgenticaSelectHistory";
9
- import type { AgenticaTextHistory } from "../histories/AgenticaTextHistory";
10
11
  import type { IAgenticaHistoryJson } from "../json/IAgenticaHistoryJson";
11
12
 
12
- import { createCancelHistory, createDescribeHistory, createExecuteHistory, createSelectHistory, createTextHistory } from "../factory/histories";
13
+ import { createAssistantMessageHistory, createCancelHistory, createDescribeHistory, createExecuteHistory, createSelectHistory, createUserMessageHistory } from "../factory/histories";
13
14
  import { createOperationSelection } from "../factory/operations";
14
15
 
15
- function transform<Model extends ILlmSchema.Model>(props: {
16
+ /**
17
+ * @internal
18
+ */
19
+ export function transformHistory<Model extends ILlmSchema.Model>(props: {
16
20
  operations: Map<string, Map<string, AgenticaOperation<Model>>>;
17
21
  history: IAgenticaHistoryJson;
18
22
  }): AgenticaHistory<Model> {
19
- // TEXT
20
- if (props.history.type === "text") {
21
- return transformText({
23
+ // USER
24
+ if (props.history.type === "userMessage") {
25
+ return transformUserMessage({
26
+ history: props.history,
27
+ });
28
+ }
29
+ // ASSISTANT
30
+ else if (props.history.type === "assistantMessage") {
31
+ return transformAssistantMessage({
22
32
  history: props.history,
23
33
  });
24
34
  }
@@ -42,19 +52,22 @@ function transform<Model extends ILlmSchema.Model>(props: {
42
52
  history: props.history,
43
53
  });
44
54
  }
45
- else if (props.history.type === "describe") {
46
- return transformDescribe({
47
- operations: props.operations,
48
- history: props.history,
49
- });
50
- }
51
- throw new Error("Invalid prompt type.");
55
+ return transformDescribe({
56
+ operations: props.operations,
57
+ history: props.history,
58
+ });
52
59
  }
53
60
 
54
- function transformText(props: {
55
- history: IAgenticaHistoryJson.IText;
56
- }): AgenticaTextHistory {
57
- return createTextHistory(props.history);
61
+ function transformAssistantMessage(props: {
62
+ history: IAgenticaHistoryJson.IAssistantMessage;
63
+ }): AgenticaAssistantMessageHistory {
64
+ return createAssistantMessageHistory(props.history);
65
+ }
66
+
67
+ function transformUserMessage(props: {
68
+ history: IAgenticaHistoryJson.IUserMessage;
69
+ }): AgenticaUserMessageHistory {
70
+ return createUserMessageHistory(props.history);
58
71
  }
59
72
 
60
73
  function transformSelect<Model extends ILlmSchema.Model>(props: {
@@ -146,12 +159,3 @@ function findOperation<Model extends ILlmSchema.Model>(props: {
146
159
  }
147
160
  return found;
148
161
  }
149
-
150
- export const AgenticaHistoryTransformer = {
151
- transform,
152
- transformText,
153
- transformSelect,
154
- transformCancel,
155
- transformExecute,
156
- transformDescribe,
157
- };
@@ -0,0 +1,320 @@
1
+ import type {
2
+ ChatCompletion,
3
+ ChatCompletionChunk,
4
+ ChatCompletionMessageToolCall,
5
+ } from "openai/resources";
6
+
7
+ import { ChatGptCompletionMessageUtil } from "./ChatGptCompletionMessageUtil";
8
+
9
+ describe("chatGptCompletionMessageUtil", () => {
10
+ describe("transformCompletionChunk", () => {
11
+ it("should transform string chunk to ChatCompletionChunk", () => {
12
+ const chunk = {
13
+ id: "test-id",
14
+ choices: [{
15
+ index: 0,
16
+ delta: { content: "Hello" },
17
+ }],
18
+ created: 1234567890,
19
+ model: "gpt-4",
20
+ object: "chat.completion.chunk",
21
+ };
22
+
23
+ const result = ChatGptCompletionMessageUtil.transformCompletionChunk(JSON.stringify(chunk));
24
+ expect(result).toEqual(chunk);
25
+ });
26
+
27
+ it("should transform Uint8Array chunk to ChatCompletionChunk", () => {
28
+ const chunk = {
29
+ id: "test-id",
30
+ choices: [{
31
+ index: 0,
32
+ delta: { content: "Hello" },
33
+ }],
34
+ created: 1234567890,
35
+ model: "gpt-4",
36
+ object: "chat.completion.chunk",
37
+ };
38
+
39
+ const uint8Array = new TextEncoder().encode(JSON.stringify(chunk));
40
+ const result = ChatGptCompletionMessageUtil.transformCompletionChunk(uint8Array);
41
+ expect(result).toEqual(chunk);
42
+ });
43
+
44
+ it("should handle invalid JSON", () => {
45
+ expect(() => {
46
+ ChatGptCompletionMessageUtil.transformCompletionChunk("invalid json");
47
+ }).toThrow();
48
+ });
49
+ });
50
+
51
+ describe("accumulate", () => {
52
+ it("should accumulate content from chunks", () => {
53
+ const origin: ChatCompletion = {
54
+ id: "test-id",
55
+ choices: [{
56
+ index: 0,
57
+ // @ts-expect-error - refusal is not required
58
+ message: { role: "assistant", content: "Hello" },
59
+ }],
60
+ created: 1234567890,
61
+ model: "gpt-4",
62
+ object: "chat.completion",
63
+ };
64
+
65
+ const chunk: ChatCompletionChunk = {
66
+ id: "test-id",
67
+ // @ts-expect-error - finish_reason is not required
68
+ choices: [{
69
+ index: 0,
70
+ delta: { content: " World" },
71
+ }],
72
+ created: 1234567890,
73
+ model: "gpt-4",
74
+ object: "chat.completion.chunk",
75
+ };
76
+
77
+ const result = ChatGptCompletionMessageUtil.accumulate(origin, chunk);
78
+ expect(result.choices[0]?.message.content).toBe("Hello World");
79
+ });
80
+
81
+ it("should accumulate tool calls", () => {
82
+ const origin: ChatCompletion = {
83
+ id: "test-id",
84
+ choices: [{
85
+ index: 0,
86
+ // @ts-expect-error - finish_reason is not required
87
+ message: {
88
+ role: "assistant",
89
+ content: null,
90
+ tool_calls: [{
91
+ id: "call_1",
92
+ type: "function",
93
+ function: {
94
+ name: "test",
95
+ arguments: "{\"arg\": \"value\"}",
96
+ },
97
+ }],
98
+ },
99
+ }],
100
+ created: 1234567890,
101
+ model: "gpt-4",
102
+ object: "chat.completion",
103
+ };
104
+
105
+ const chunk: ChatCompletionChunk = {
106
+ id: "test-id",
107
+ // @ts-expect-error - finish_reason is not required
108
+ choices: [{
109
+ index: 0,
110
+ delta: {
111
+ tool_calls: [{
112
+ index: 0,
113
+ id: "call_1",
114
+ function: {
115
+ name: "_function",
116
+ arguments: "{\"arg2\": \"value2\"}",
117
+ },
118
+ }],
119
+ },
120
+ }],
121
+ created: 1234567890,
122
+ model: "gpt-4",
123
+ object: "chat.completion.chunk",
124
+ };
125
+
126
+ const result = ChatGptCompletionMessageUtil.accumulate(origin, chunk);
127
+ expect(result.choices[0]?.message.tool_calls?.[0]?.function.name).toBe("test_function");
128
+ expect(result.choices[0]?.message.tool_calls?.[0]?.function.arguments).toBe("{\"arg\": \"value\"}{\"arg2\": \"value2\"}");
129
+ });
130
+
131
+ it("should handle usage aggregation", () => {
132
+ const origin: ChatCompletion = {
133
+ id: "test-id",
134
+ choices: [{
135
+ index: 0,
136
+ // @ts-expect-error - finish_reason is not required
137
+ message: { role: "assistant", content: "Hello" },
138
+ }],
139
+ created: 1234567890,
140
+ model: "gpt-4",
141
+ object: "chat.completion",
142
+ usage: {
143
+ prompt_tokens: 10,
144
+ completion_tokens: 5,
145
+ total_tokens: 15,
146
+ },
147
+ };
148
+
149
+ const chunk: ChatCompletionChunk = {
150
+ id: "test-id",
151
+ // @ts-expect-error - finish_reason is not required
152
+ choices: [{
153
+ index: 0,
154
+ delta: { content: " World" },
155
+ }],
156
+ created: 1234567890,
157
+ model: "gpt-4",
158
+ object: "chat.completion.chunk",
159
+ usage: {
160
+ prompt_tokens: 0,
161
+ completion_tokens: 6,
162
+ total_tokens: 6,
163
+ },
164
+ };
165
+
166
+ const result = ChatGptCompletionMessageUtil.accumulate(origin, chunk);
167
+ expect(result.usage).toEqual({
168
+ prompt_tokens: 10,
169
+ completion_tokens: 11,
170
+ total_tokens: 21,
171
+ completion_tokens_details: {
172
+ accepted_prediction_tokens: 0,
173
+ reasoning_tokens: 0,
174
+ rejected_prediction_tokens: 0,
175
+ },
176
+ prompt_tokens_details: {
177
+ audio_tokens: 0,
178
+ cached_tokens: 0,
179
+ },
180
+ });
181
+ });
182
+ });
183
+
184
+ describe("merge", () => {
185
+ it("should merge multiple chunks into completion", () => {
186
+ const chunks: ChatCompletionChunk[] = [
187
+ {
188
+ id: "test-id",
189
+ // @ts-expect-error - finish_reason is not required
190
+ choices: [{
191
+ index: 0,
192
+ delta: { content: "Hello" },
193
+ }],
194
+ created: 1234567890,
195
+ model: "gpt-4",
196
+ object: "chat.completion.chunk",
197
+ },
198
+ {
199
+ id: "test-id",
200
+ // @ts-expect-error - finish_reason is not required
201
+ choices: [{
202
+ index: 0,
203
+ delta: { content: " World" },
204
+ }],
205
+ created: 1234567890,
206
+ model: "gpt-4",
207
+ object: "chat.completion.chunk",
208
+ },
209
+ ];
210
+
211
+ const result = ChatGptCompletionMessageUtil.merge(chunks);
212
+ expect(result.choices[0]?.message.content).toBe("Hello World");
213
+ });
214
+
215
+ it("should throw error for empty chunks array", () => {
216
+ expect(() => {
217
+ ChatGptCompletionMessageUtil.merge([]);
218
+ }).toThrow("No chunks received");
219
+ });
220
+ });
221
+
222
+ describe("mergeChoice", () => {
223
+ it("should merge finish reason", () => {
224
+ const acc: ChatCompletion.Choice = {
225
+ index: 0,
226
+ // @ts-expect-error - finish_reason is not required
227
+ message: { role: "assistant", content: "Hello" },
228
+ };
229
+
230
+ const cur: ChatCompletionChunk.Choice = {
231
+ index: 0,
232
+ delta: {},
233
+ finish_reason: "stop",
234
+ };
235
+
236
+ const result = ChatGptCompletionMessageUtil.mergeChoice(acc, cur);
237
+ expect(result.finish_reason).toBe("stop");
238
+ });
239
+
240
+ it("should merge content", () => {
241
+ const acc: ChatCompletion.Choice = {
242
+ index: 0,
243
+ // @ts-expect-error - refusal is not required
244
+ message: { role: "assistant", content: "Hello" },
245
+ };
246
+
247
+ // @ts-expect-error - finish_reason is not required
248
+ const cur: ChatCompletionChunk.Choice = {
249
+ index: 0,
250
+ delta: { content: " World" },
251
+ };
252
+
253
+ const result = ChatGptCompletionMessageUtil.mergeChoice(acc, cur);
254
+ expect(result.message.content).toBe("Hello World");
255
+ });
256
+
257
+ it("should merge refusal", () => {
258
+ // @ts-expect-error - finish_reason is not required
259
+ const acc: ChatCompletion.Choice = {
260
+ index: 0,
261
+ message: { role: "assistant", content: null, refusal: "I cannot" },
262
+ };
263
+
264
+ // @ts-expect-error - finish_reason is not required
265
+ const cur: ChatCompletionChunk.Choice = {
266
+ index: 0,
267
+ delta: { refusal: " do that" },
268
+ };
269
+
270
+ const result = ChatGptCompletionMessageUtil.mergeChoice(acc, cur);
271
+ expect(result.message.refusal).toBe("I cannot do that");
272
+ });
273
+ });
274
+
275
+ describe("mergeToolCalls", () => {
276
+ it("should merge tool call function arguments", () => {
277
+ const acc: ChatCompletionMessageToolCall = {
278
+ id: "call_1",
279
+ type: "function",
280
+ function: {
281
+ name: "test",
282
+ arguments: "{\"arg\": \"value\"}",
283
+ },
284
+ };
285
+
286
+ const cur: ChatCompletionChunk.Choice.Delta.ToolCall = {
287
+ index: 0,
288
+ id: "call_1",
289
+ function: {
290
+ arguments: "{\"arg2\": \"value2\"}",
291
+ },
292
+ };
293
+
294
+ const result = ChatGptCompletionMessageUtil.mergeToolCalls(acc, cur);
295
+ expect(result.function.arguments).toBe("{\"arg\": \"value\"}{\"arg2\": \"value2\"}");
296
+ });
297
+
298
+ it("should merge tool call function name", () => {
299
+ const acc: ChatCompletionMessageToolCall = {
300
+ id: "call_1",
301
+ type: "function",
302
+ function: {
303
+ name: "test",
304
+ arguments: "",
305
+ },
306
+ };
307
+
308
+ const cur: ChatCompletionChunk.Choice.Delta.ToolCall = {
309
+ index: 0,
310
+ id: "call_1",
311
+ function: {
312
+ name: "_function",
313
+ },
314
+ };
315
+
316
+ const result = ChatGptCompletionMessageUtil.mergeToolCalls(acc, cur);
317
+ expect(result.function.name).toBe("test_function");
318
+ });
319
+ });
320
+ });