@ax-llm/ax 12.0.15 → 12.0.17
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/index.cjs +497 -159
- package/index.cjs.map +1 -1
- package/index.d.cts +139 -3
- package/index.d.ts +139 -3
- package/index.js +495 -159
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,71 +1,3 @@
|
|
|
1
|
-
// ai/base.ts
|
|
2
|
-
import crypto2 from "crypto";
|
|
3
|
-
import { context, SpanKind } from "@opentelemetry/api";
|
|
4
|
-
|
|
5
|
-
// trace/trace.ts
|
|
6
|
-
var axSpanAttributes = {
|
|
7
|
-
// LLM
|
|
8
|
-
LLM_SYSTEM: "gen_ai.system",
|
|
9
|
-
LLM_OPERATION_NAME: "gen_ai.operation.name",
|
|
10
|
-
LLM_REQUEST_MODEL: "gen_ai.request.model",
|
|
11
|
-
LLM_REQUEST_MAX_TOKENS: "gen_ai.request.max_tokens",
|
|
12
|
-
LLM_REQUEST_TEMPERATURE: "gen_ai.request.temperature",
|
|
13
|
-
LLM_REQUEST_TOP_K: "gen_ai.request.top_k",
|
|
14
|
-
LLM_REQUEST_FREQUENCY_PENALTY: "gen_ai.request.frequency_penalty",
|
|
15
|
-
LLM_REQUEST_PRESENCE_PENALTY: "gen_ai.request.presence_penalty",
|
|
16
|
-
LLM_REQUEST_STOP_SEQUENCES: "gen_ai.request.stop_sequences",
|
|
17
|
-
LLM_REQUEST_LLM_IS_STREAMING: "gen_ai.request.llm_is_streaming",
|
|
18
|
-
LLM_REQUEST_TOP_P: "gen_ai.request.top_p",
|
|
19
|
-
LLM_USAGE_INPUT_TOKENS: "gen_ai.usage.input_tokens",
|
|
20
|
-
LLM_USAGE_OUTPUT_TOKENS: "gen_ai.usage.output_tokens",
|
|
21
|
-
LLM_USAGE_TOTAL_TOKENS: "gen_ai.usage.total_tokens",
|
|
22
|
-
LLM_USAGE_THOUGHTS_TOKENS: "gen_ai.usage.thoughts_tokens",
|
|
23
|
-
// Vector DB
|
|
24
|
-
DB_SYSTEM: "db.system",
|
|
25
|
-
DB_TABLE: "db.table",
|
|
26
|
-
DB_NAMESPACE: "db.namespace",
|
|
27
|
-
DB_ID: "db.id",
|
|
28
|
-
DB_QUERY_TEXT: "db.query.text",
|
|
29
|
-
DB_VECTOR: "db.vector",
|
|
30
|
-
DB_OPERATION_NAME: "db.operation.name",
|
|
31
|
-
DB_VECTOR_QUERY_TOP_K: "db.vector.query.top_k",
|
|
32
|
-
DB_QUERY_EMBEDDINGS: "db.query.embeddings",
|
|
33
|
-
DB_QUERY_RESULT: "db.query.result",
|
|
34
|
-
// Query Embeddings
|
|
35
|
-
DB_QUERY_EMBEDDINGS_VECTOR: "db.query.embeddings.vector",
|
|
36
|
-
// Query Result (canonical format)
|
|
37
|
-
DB_QUERY_RESULT_ID: "db.query.result.id",
|
|
38
|
-
DB_QUERY_RESULT_SCORE: "db.query.result.score",
|
|
39
|
-
DB_QUERY_RESULT_DISTANCE: "db.query.result.distance",
|
|
40
|
-
DB_QUERY_RESULT_METADATA: "db.query.result.metadata",
|
|
41
|
-
DB_QUERY_RESULT_VECTOR: "db.query.result.vector",
|
|
42
|
-
DB_QUERY_RESULT_DOCUMENT: "db.query.result.document"
|
|
43
|
-
};
|
|
44
|
-
var axSpanEvents = {
|
|
45
|
-
GEN_AI_USER_MESSAGE: "gen_ai.user.message",
|
|
46
|
-
GEN_AI_SYSTEM_MESSAGE: "gen_ai.system.message",
|
|
47
|
-
GEN_AI_ASSISTANT_MESSAGE: "gen_ai.assistant.message",
|
|
48
|
-
GEN_AI_TOOL_MESSAGE: "gen_ai.tool.message",
|
|
49
|
-
// For tool messages in request & response tool calls
|
|
50
|
-
GEN_AI_CHOICE: "gen_ai.choice",
|
|
51
|
-
GEN_AI_USAGE: "gen_ai.usage"
|
|
52
|
-
};
|
|
53
|
-
var AxLLMRequestTypeValues = /* @__PURE__ */ ((AxLLMRequestTypeValues2) => {
|
|
54
|
-
AxLLMRequestTypeValues2["COMPLETION"] = "completion";
|
|
55
|
-
AxLLMRequestTypeValues2["CHAT"] = "chat";
|
|
56
|
-
AxLLMRequestTypeValues2["RERANK"] = "rerank";
|
|
57
|
-
AxLLMRequestTypeValues2["UNKNOWN"] = "unknown";
|
|
58
|
-
return AxLLMRequestTypeValues2;
|
|
59
|
-
})(AxLLMRequestTypeValues || {});
|
|
60
|
-
var AxSpanKindValues = /* @__PURE__ */ ((AxSpanKindValues2) => {
|
|
61
|
-
AxSpanKindValues2["WORKFLOW"] = "workflow";
|
|
62
|
-
AxSpanKindValues2["TASK"] = "task";
|
|
63
|
-
AxSpanKindValues2["AGENT"] = "agent";
|
|
64
|
-
AxSpanKindValues2["TOOL"] = "tool";
|
|
65
|
-
AxSpanKindValues2["UNKNOWN"] = "unknown";
|
|
66
|
-
return AxSpanKindValues2;
|
|
67
|
-
})(AxSpanKindValues || {});
|
|
68
|
-
|
|
69
1
|
// util/apicall.ts
|
|
70
2
|
import crypto from "crypto";
|
|
71
3
|
import {
|
|
@@ -320,6 +252,33 @@ var AxAIServiceAuthenticationError = class extends AxAIServiceError {
|
|
|
320
252
|
this.name = this.constructor.name;
|
|
321
253
|
}
|
|
322
254
|
};
|
|
255
|
+
var AxAIRefusalError = class extends Error {
|
|
256
|
+
constructor(refusalMessage, model, requestId) {
|
|
257
|
+
super(`Model refused to fulfill request: ${refusalMessage}`);
|
|
258
|
+
this.refusalMessage = refusalMessage;
|
|
259
|
+
this.model = model;
|
|
260
|
+
this.requestId = requestId;
|
|
261
|
+
this.name = "AxAIRefusalError";
|
|
262
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
263
|
+
this.errorId = crypto.randomUUID();
|
|
264
|
+
}
|
|
265
|
+
timestamp;
|
|
266
|
+
errorId;
|
|
267
|
+
toString() {
|
|
268
|
+
return [
|
|
269
|
+
`${this.name}: ${this.message}`,
|
|
270
|
+
`Refusal: ${this.refusalMessage}`,
|
|
271
|
+
this.model ? `Model: ${this.model}` : "",
|
|
272
|
+
this.requestId ? `Request ID: ${this.requestId}` : "",
|
|
273
|
+
`Timestamp: ${this.timestamp}`,
|
|
274
|
+
`Error ID: ${this.errorId}`
|
|
275
|
+
].filter(Boolean).join("\n");
|
|
276
|
+
}
|
|
277
|
+
// For Node.js, override the custom inspect method so console.log shows our custom string.
|
|
278
|
+
[Symbol.for("nodejs.util.inspect.custom")](_depth, _options) {
|
|
279
|
+
return this.toString();
|
|
280
|
+
}
|
|
281
|
+
};
|
|
323
282
|
async function safeReadResponseBody(response) {
|
|
324
283
|
try {
|
|
325
284
|
if (response.headers.get("content-type")?.includes("application/json")) {
|
|
@@ -623,6 +582,74 @@ var apiCall = async (api, json) => {
|
|
|
623
582
|
}
|
|
624
583
|
};
|
|
625
584
|
|
|
585
|
+
// ai/base.ts
|
|
586
|
+
import crypto2 from "crypto";
|
|
587
|
+
import { context, SpanKind } from "@opentelemetry/api";
|
|
588
|
+
|
|
589
|
+
// trace/trace.ts
|
|
590
|
+
var axSpanAttributes = {
|
|
591
|
+
// LLM
|
|
592
|
+
LLM_SYSTEM: "gen_ai.system",
|
|
593
|
+
LLM_OPERATION_NAME: "gen_ai.operation.name",
|
|
594
|
+
LLM_REQUEST_MODEL: "gen_ai.request.model",
|
|
595
|
+
LLM_REQUEST_MAX_TOKENS: "gen_ai.request.max_tokens",
|
|
596
|
+
LLM_REQUEST_TEMPERATURE: "gen_ai.request.temperature",
|
|
597
|
+
LLM_REQUEST_TOP_K: "gen_ai.request.top_k",
|
|
598
|
+
LLM_REQUEST_FREQUENCY_PENALTY: "gen_ai.request.frequency_penalty",
|
|
599
|
+
LLM_REQUEST_PRESENCE_PENALTY: "gen_ai.request.presence_penalty",
|
|
600
|
+
LLM_REQUEST_STOP_SEQUENCES: "gen_ai.request.stop_sequences",
|
|
601
|
+
LLM_REQUEST_LLM_IS_STREAMING: "gen_ai.request.llm_is_streaming",
|
|
602
|
+
LLM_REQUEST_TOP_P: "gen_ai.request.top_p",
|
|
603
|
+
LLM_USAGE_INPUT_TOKENS: "gen_ai.usage.input_tokens",
|
|
604
|
+
LLM_USAGE_OUTPUT_TOKENS: "gen_ai.usage.output_tokens",
|
|
605
|
+
LLM_USAGE_TOTAL_TOKENS: "gen_ai.usage.total_tokens",
|
|
606
|
+
LLM_USAGE_THOUGHTS_TOKENS: "gen_ai.usage.thoughts_tokens",
|
|
607
|
+
// Vector DB
|
|
608
|
+
DB_SYSTEM: "db.system",
|
|
609
|
+
DB_TABLE: "db.table",
|
|
610
|
+
DB_NAMESPACE: "db.namespace",
|
|
611
|
+
DB_ID: "db.id",
|
|
612
|
+
DB_QUERY_TEXT: "db.query.text",
|
|
613
|
+
DB_VECTOR: "db.vector",
|
|
614
|
+
DB_OPERATION_NAME: "db.operation.name",
|
|
615
|
+
DB_VECTOR_QUERY_TOP_K: "db.vector.query.top_k",
|
|
616
|
+
DB_QUERY_EMBEDDINGS: "db.query.embeddings",
|
|
617
|
+
DB_QUERY_RESULT: "db.query.result",
|
|
618
|
+
// Query Embeddings
|
|
619
|
+
DB_QUERY_EMBEDDINGS_VECTOR: "db.query.embeddings.vector",
|
|
620
|
+
// Query Result (canonical format)
|
|
621
|
+
DB_QUERY_RESULT_ID: "db.query.result.id",
|
|
622
|
+
DB_QUERY_RESULT_SCORE: "db.query.result.score",
|
|
623
|
+
DB_QUERY_RESULT_DISTANCE: "db.query.result.distance",
|
|
624
|
+
DB_QUERY_RESULT_METADATA: "db.query.result.metadata",
|
|
625
|
+
DB_QUERY_RESULT_VECTOR: "db.query.result.vector",
|
|
626
|
+
DB_QUERY_RESULT_DOCUMENT: "db.query.result.document"
|
|
627
|
+
};
|
|
628
|
+
var axSpanEvents = {
|
|
629
|
+
GEN_AI_USER_MESSAGE: "gen_ai.user.message",
|
|
630
|
+
GEN_AI_SYSTEM_MESSAGE: "gen_ai.system.message",
|
|
631
|
+
GEN_AI_ASSISTANT_MESSAGE: "gen_ai.assistant.message",
|
|
632
|
+
GEN_AI_TOOL_MESSAGE: "gen_ai.tool.message",
|
|
633
|
+
// For tool messages in request & response tool calls
|
|
634
|
+
GEN_AI_CHOICE: "gen_ai.choice",
|
|
635
|
+
GEN_AI_USAGE: "gen_ai.usage"
|
|
636
|
+
};
|
|
637
|
+
var AxLLMRequestTypeValues = /* @__PURE__ */ ((AxLLMRequestTypeValues2) => {
|
|
638
|
+
AxLLMRequestTypeValues2["COMPLETION"] = "completion";
|
|
639
|
+
AxLLMRequestTypeValues2["CHAT"] = "chat";
|
|
640
|
+
AxLLMRequestTypeValues2["RERANK"] = "rerank";
|
|
641
|
+
AxLLMRequestTypeValues2["UNKNOWN"] = "unknown";
|
|
642
|
+
return AxLLMRequestTypeValues2;
|
|
643
|
+
})(AxLLMRequestTypeValues || {});
|
|
644
|
+
var AxSpanKindValues = /* @__PURE__ */ ((AxSpanKindValues2) => {
|
|
645
|
+
AxSpanKindValues2["WORKFLOW"] = "workflow";
|
|
646
|
+
AxSpanKindValues2["TASK"] = "task";
|
|
647
|
+
AxSpanKindValues2["AGENT"] = "agent";
|
|
648
|
+
AxSpanKindValues2["TOOL"] = "tool";
|
|
649
|
+
AxSpanKindValues2["UNKNOWN"] = "unknown";
|
|
650
|
+
return AxSpanKindValues2;
|
|
651
|
+
})(AxSpanKindValues || {});
|
|
652
|
+
|
|
626
653
|
// util/transform.ts
|
|
627
654
|
import {
|
|
628
655
|
TransformStream as TransformStream4
|
|
@@ -1988,7 +2015,13 @@ var AxAIAnthropicImpl = class {
|
|
|
1988
2015
|
};
|
|
1989
2016
|
createChatResp = (resp) => {
|
|
1990
2017
|
if (resp.type === "error") {
|
|
1991
|
-
throw new
|
|
2018
|
+
throw new AxAIRefusalError(
|
|
2019
|
+
resp.error.message,
|
|
2020
|
+
void 0,
|
|
2021
|
+
// model not specified in error response
|
|
2022
|
+
void 0
|
|
2023
|
+
// requestId not specified in error response
|
|
2024
|
+
);
|
|
1992
2025
|
}
|
|
1993
2026
|
const finishReason = mapFinishReason(resp.stop_reason);
|
|
1994
2027
|
const showThoughts = this.currentPromptConfig?.thinkingTokenBudget !== "none" && this.currentPromptConfig?.showThoughts !== false;
|
|
@@ -2044,7 +2077,13 @@ var AxAIAnthropicImpl = class {
|
|
|
2044
2077
|
}
|
|
2045
2078
|
if (resp.type === "error") {
|
|
2046
2079
|
const { error } = resp;
|
|
2047
|
-
throw new
|
|
2080
|
+
throw new AxAIRefusalError(
|
|
2081
|
+
error.message,
|
|
2082
|
+
void 0,
|
|
2083
|
+
// model not specified in error event
|
|
2084
|
+
void 0
|
|
2085
|
+
// requestId not specified in error event
|
|
2086
|
+
);
|
|
2048
2087
|
}
|
|
2049
2088
|
const index = 0;
|
|
2050
2089
|
if (resp.type === "message_start") {
|
|
@@ -2672,6 +2711,9 @@ var AxAIOpenAIImpl = class {
|
|
|
2672
2711
|
totalTokens: usage.total_tokens
|
|
2673
2712
|
} : void 0;
|
|
2674
2713
|
const results = choices.map((choice) => {
|
|
2714
|
+
if (choice.message.refusal) {
|
|
2715
|
+
throw new AxAIRefusalError(choice.message.refusal, resp.model, resp.id);
|
|
2716
|
+
}
|
|
2675
2717
|
const finishReason = mapFinishReason2(choice.finish_reason);
|
|
2676
2718
|
const functionCalls = choice.message.tool_calls?.map(
|
|
2677
2719
|
({ id: id2, function: { arguments: params, name } }) => ({
|
|
@@ -2683,8 +2725,9 @@ var AxAIOpenAIImpl = class {
|
|
|
2683
2725
|
return {
|
|
2684
2726
|
index: choice.index,
|
|
2685
2727
|
id: `${choice.index}`,
|
|
2686
|
-
content: choice.message.content,
|
|
2728
|
+
content: choice.message.content ?? void 0,
|
|
2687
2729
|
thought: choice.message.reasoning_content,
|
|
2730
|
+
annotations: choice.message.annotations,
|
|
2688
2731
|
functionCalls,
|
|
2689
2732
|
finishReason
|
|
2690
2733
|
};
|
|
@@ -2711,11 +2754,16 @@ var AxAIOpenAIImpl = class {
|
|
|
2711
2754
|
delta: {
|
|
2712
2755
|
content,
|
|
2713
2756
|
role,
|
|
2757
|
+
refusal,
|
|
2714
2758
|
tool_calls: toolCalls,
|
|
2715
|
-
reasoning_content: thought
|
|
2759
|
+
reasoning_content: thought,
|
|
2760
|
+
annotations
|
|
2716
2761
|
},
|
|
2717
2762
|
finish_reason: oaiFinishReason
|
|
2718
2763
|
}) => {
|
|
2764
|
+
if (refusal) {
|
|
2765
|
+
throw new AxAIRefusalError(refusal, void 0, id);
|
|
2766
|
+
}
|
|
2719
2767
|
const finishReason = mapFinishReason2(oaiFinishReason);
|
|
2720
2768
|
const functionCalls = toolCalls?.map(({ id: _id, index: index2, function: { name, arguments: params } }) => {
|
|
2721
2769
|
if (typeof _id === "string" && typeof index2 === "number" && !sstate.indexIdMap[index2]) {
|
|
@@ -2733,9 +2781,10 @@ var AxAIOpenAIImpl = class {
|
|
|
2733
2781
|
}).filter((v) => v !== null);
|
|
2734
2782
|
return {
|
|
2735
2783
|
index,
|
|
2736
|
-
content,
|
|
2784
|
+
content: content ?? void 0,
|
|
2737
2785
|
role,
|
|
2738
2786
|
thought,
|
|
2787
|
+
annotations,
|
|
2739
2788
|
functionCalls,
|
|
2740
2789
|
finishReason,
|
|
2741
2790
|
id
|
|
@@ -3832,11 +3881,29 @@ var AxAIGoogleGeminiImpl = class {
|
|
|
3832
3881
|
result.finishReason = "stop";
|
|
3833
3882
|
break;
|
|
3834
3883
|
case "SAFETY":
|
|
3835
|
-
throw new
|
|
3884
|
+
throw new AxAIRefusalError(
|
|
3885
|
+
"Content was blocked due to safety settings",
|
|
3886
|
+
void 0,
|
|
3887
|
+
// model not available in candidate
|
|
3888
|
+
void 0
|
|
3889
|
+
// requestId not available
|
|
3890
|
+
);
|
|
3836
3891
|
case "RECITATION":
|
|
3837
|
-
throw new
|
|
3892
|
+
throw new AxAIRefusalError(
|
|
3893
|
+
"Content was blocked due to recitation policy",
|
|
3894
|
+
void 0,
|
|
3895
|
+
// model not available in candidate
|
|
3896
|
+
void 0
|
|
3897
|
+
// requestId not available
|
|
3898
|
+
);
|
|
3838
3899
|
case "MALFORMED_FUNCTION_CALL":
|
|
3839
|
-
throw new
|
|
3900
|
+
throw new AxAIRefusalError(
|
|
3901
|
+
"Function call was malformed and blocked",
|
|
3902
|
+
void 0,
|
|
3903
|
+
// model not available in candidate
|
|
3904
|
+
void 0
|
|
3905
|
+
// requestId not available
|
|
3906
|
+
);
|
|
3840
3907
|
}
|
|
3841
3908
|
if (!candidate.content || !candidate.content.parts) {
|
|
3842
3909
|
return result;
|
|
@@ -4714,7 +4781,7 @@ var AxAIOpenAIResponsesImpl = class {
|
|
|
4714
4781
|
switch (item.type) {
|
|
4715
4782
|
case "message":
|
|
4716
4783
|
currentResult.id = item.id;
|
|
4717
|
-
currentResult.content = contentToText(item.content);
|
|
4784
|
+
currentResult.content = contentToText(item.content, id);
|
|
4718
4785
|
currentResult.finishReason = item.status === "completed" ? "stop" : "content_filter";
|
|
4719
4786
|
break;
|
|
4720
4787
|
case "reasoning":
|
|
@@ -4887,7 +4954,10 @@ var AxAIOpenAIResponsesImpl = class {
|
|
|
4887
4954
|
switch (event.item.type) {
|
|
4888
4955
|
case "message":
|
|
4889
4956
|
baseResult.id = event.item.id;
|
|
4890
|
-
baseResult.content = contentToText(
|
|
4957
|
+
baseResult.content = contentToText(
|
|
4958
|
+
event.item.content,
|
|
4959
|
+
event.item.id
|
|
4960
|
+
);
|
|
4891
4961
|
break;
|
|
4892
4962
|
case "function_call":
|
|
4893
4963
|
baseResult.id = event.item.id;
|
|
@@ -5057,7 +5127,7 @@ var AxAIOpenAIResponsesImpl = class {
|
|
|
5057
5127
|
break;
|
|
5058
5128
|
case "response.content_part.added":
|
|
5059
5129
|
baseResult.id = event.item_id;
|
|
5060
|
-
baseResult.content = contentToText([event.part]);
|
|
5130
|
+
baseResult.content = contentToText([event.part], event.item_id);
|
|
5061
5131
|
break;
|
|
5062
5132
|
case "response.output_text.delta":
|
|
5063
5133
|
baseResult.id = event.item_id;
|
|
@@ -5242,11 +5312,13 @@ var AxAIOpenAIResponsesImpl = class {
|
|
|
5242
5312
|
return [apiConfig, reqValue];
|
|
5243
5313
|
}
|
|
5244
5314
|
};
|
|
5245
|
-
var contentToText = (content) => {
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5315
|
+
var contentToText = (content, responseId) => {
|
|
5316
|
+
const refusalContent = content.filter((c) => c.type === "refusal");
|
|
5317
|
+
if (refusalContent.length > 0) {
|
|
5318
|
+
const refusalMessage = refusalContent.map((c) => c.refusal).join("\n");
|
|
5319
|
+
throw new AxAIRefusalError(refusalMessage, void 0, responseId);
|
|
5320
|
+
}
|
|
5321
|
+
return content.filter((c) => c.type === "output_text").map((c) => c.text).join("\n");
|
|
5250
5322
|
};
|
|
5251
5323
|
|
|
5252
5324
|
// ai/openai/responses_api_base.ts
|
|
@@ -5834,213 +5906,279 @@ import {
|
|
|
5834
5906
|
|
|
5835
5907
|
// ai/validate.ts
|
|
5836
5908
|
function axValidateChatRequestMessage(item) {
|
|
5909
|
+
const value = (v) => JSON.stringify(v, null, 2);
|
|
5837
5910
|
if (!item) {
|
|
5838
|
-
throw new Error(
|
|
5911
|
+
throw new Error(
|
|
5912
|
+
`Chat request message item cannot be null or undefined, received: ${value(item)}`
|
|
5913
|
+
);
|
|
5839
5914
|
}
|
|
5840
|
-
|
|
5841
|
-
|
|
5915
|
+
const role = item?.role;
|
|
5916
|
+
if (!role) {
|
|
5917
|
+
throw new Error(
|
|
5918
|
+
`Chat request message must have a role, received: ${value(role)}`
|
|
5919
|
+
);
|
|
5842
5920
|
}
|
|
5843
|
-
switch (
|
|
5844
|
-
case "system":
|
|
5845
|
-
|
|
5921
|
+
switch (role) {
|
|
5922
|
+
case "system": {
|
|
5923
|
+
const systemItem = item;
|
|
5924
|
+
if (!systemItem.content || systemItem.content.trim() === "") {
|
|
5846
5925
|
throw new Error(
|
|
5847
|
-
|
|
5926
|
+
`System message content cannot be empty or whitespace-only, received: ${value(systemItem.content)}`
|
|
5848
5927
|
);
|
|
5849
5928
|
}
|
|
5850
5929
|
break;
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5930
|
+
}
|
|
5931
|
+
case "user": {
|
|
5932
|
+
const userItem = item;
|
|
5933
|
+
if (!userItem.content) {
|
|
5934
|
+
throw new Error(
|
|
5935
|
+
`User message content cannot be undefined, received: ${value(userItem.content)}`
|
|
5936
|
+
);
|
|
5854
5937
|
}
|
|
5855
|
-
if (typeof
|
|
5856
|
-
if (
|
|
5938
|
+
if (typeof userItem.content === "string") {
|
|
5939
|
+
if (userItem.content.trim() === "") {
|
|
5857
5940
|
throw new Error(
|
|
5858
|
-
|
|
5941
|
+
`User message content cannot be empty or whitespace-only, received: ${value(userItem.content)}`
|
|
5859
5942
|
);
|
|
5860
5943
|
}
|
|
5861
|
-
} else if (Array.isArray(
|
|
5862
|
-
if (
|
|
5863
|
-
throw new Error(
|
|
5944
|
+
} else if (Array.isArray(userItem.content)) {
|
|
5945
|
+
if (userItem.content.length === 0) {
|
|
5946
|
+
throw new Error(
|
|
5947
|
+
`User message content array cannot be empty, received: ${value(userItem.content)}`
|
|
5948
|
+
);
|
|
5864
5949
|
}
|
|
5865
|
-
for (let index = 0; index <
|
|
5866
|
-
const contentItem =
|
|
5950
|
+
for (let index = 0; index < userItem.content.length; index++) {
|
|
5951
|
+
const contentItem = userItem.content[index];
|
|
5867
5952
|
if (!contentItem || typeof contentItem !== "object") {
|
|
5868
5953
|
throw new Error(
|
|
5869
|
-
`User message content item at index ${index} must be an object`
|
|
5954
|
+
`User message content item at index ${index} must be an object, received: ${value(contentItem)}`
|
|
5870
5955
|
);
|
|
5871
5956
|
}
|
|
5872
|
-
|
|
5957
|
+
const contentType = contentItem?.type;
|
|
5958
|
+
if (!contentType) {
|
|
5873
5959
|
throw new Error(
|
|
5874
|
-
`User message content item at index ${index} must have a type`
|
|
5960
|
+
`User message content item at index ${index} must have a type, received: ${value(contentType)}`
|
|
5875
5961
|
);
|
|
5876
5962
|
}
|
|
5877
|
-
switch (
|
|
5878
|
-
case "text":
|
|
5879
|
-
|
|
5963
|
+
switch (contentType) {
|
|
5964
|
+
case "text": {
|
|
5965
|
+
const textItem = contentItem;
|
|
5966
|
+
if (!textItem.text || textItem.text.trim() === "") {
|
|
5880
5967
|
throw new Error(
|
|
5881
|
-
`User message text content at index ${index} cannot be empty or whitespace-only`
|
|
5968
|
+
`User message text content at index ${index} cannot be empty or whitespace-only, received: ${value(textItem.text)}`
|
|
5882
5969
|
);
|
|
5883
5970
|
}
|
|
5884
5971
|
break;
|
|
5885
|
-
|
|
5886
|
-
|
|
5972
|
+
}
|
|
5973
|
+
case "image": {
|
|
5974
|
+
const imageItem = contentItem;
|
|
5975
|
+
if (!imageItem.image || imageItem.image.trim() === "") {
|
|
5887
5976
|
throw new Error(
|
|
5888
|
-
`User message image content at index ${index} cannot be empty`
|
|
5977
|
+
`User message image content at index ${index} cannot be empty, received: ${value(imageItem.image)}`
|
|
5889
5978
|
);
|
|
5890
5979
|
}
|
|
5891
|
-
if (!
|
|
5980
|
+
if (!imageItem.mimeType || imageItem.mimeType.trim() === "") {
|
|
5892
5981
|
throw new Error(
|
|
5893
|
-
`User message image content at index ${index} must have a mimeType`
|
|
5982
|
+
`User message image content at index ${index} must have a mimeType, received: ${value(imageItem.mimeType)}`
|
|
5894
5983
|
);
|
|
5895
5984
|
}
|
|
5896
5985
|
break;
|
|
5897
|
-
|
|
5898
|
-
|
|
5986
|
+
}
|
|
5987
|
+
case "audio": {
|
|
5988
|
+
const audioItem = contentItem;
|
|
5989
|
+
if (!audioItem.data || audioItem.data.trim() === "") {
|
|
5899
5990
|
throw new Error(
|
|
5900
|
-
`User message audio content at index ${index} cannot be empty`
|
|
5991
|
+
`User message audio content at index ${index} cannot be empty, received: ${value(audioItem.data)}`
|
|
5901
5992
|
);
|
|
5902
5993
|
}
|
|
5903
5994
|
break;
|
|
5995
|
+
}
|
|
5904
5996
|
default:
|
|
5905
5997
|
throw new Error(
|
|
5906
|
-
`User message content item at index ${index} has unsupported type: ${
|
|
5998
|
+
`User message content item at index ${index} has unsupported type: ${value(contentType)}`
|
|
5907
5999
|
);
|
|
5908
6000
|
}
|
|
5909
6001
|
}
|
|
5910
6002
|
} else {
|
|
5911
6003
|
throw new Error(
|
|
5912
|
-
|
|
6004
|
+
`User message content must be a string or array of content objects, received: ${value(userItem.content)}`
|
|
5913
6005
|
);
|
|
5914
6006
|
}
|
|
5915
6007
|
break;
|
|
5916
|
-
|
|
5917
|
-
|
|
6008
|
+
}
|
|
6009
|
+
case "assistant": {
|
|
6010
|
+
const assistantItem = item;
|
|
6011
|
+
if (!assistantItem.content && !assistantItem.functionCalls) {
|
|
5918
6012
|
throw new Error(
|
|
5919
|
-
|
|
6013
|
+
`Assistant message must have either content or function calls, received content: ${value(assistantItem.content)}, functionCalls: ${value(assistantItem.functionCalls)}`
|
|
5920
6014
|
);
|
|
5921
6015
|
}
|
|
5922
|
-
if (
|
|
5923
|
-
throw new Error(
|
|
6016
|
+
if (assistantItem.content && typeof assistantItem.content !== "string") {
|
|
6017
|
+
throw new Error(
|
|
6018
|
+
`Assistant message content must be a string, received: ${value(assistantItem.content)}`
|
|
6019
|
+
);
|
|
5924
6020
|
}
|
|
5925
|
-
if (
|
|
5926
|
-
throw new Error(
|
|
6021
|
+
if (assistantItem.functionCalls && !Array.isArray(assistantItem.functionCalls)) {
|
|
6022
|
+
throw new Error(
|
|
6023
|
+
`Assistant message function calls must be an array, received: ${value(assistantItem.functionCalls)}`
|
|
6024
|
+
);
|
|
5927
6025
|
}
|
|
5928
6026
|
break;
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
6027
|
+
}
|
|
6028
|
+
case "function": {
|
|
6029
|
+
const functionItem = item;
|
|
6030
|
+
if (!functionItem.functionId || functionItem.functionId.trim() === "") {
|
|
6031
|
+
throw new Error(
|
|
6032
|
+
`Function message must have a non-empty functionId, received: ${value(functionItem.functionId)}`
|
|
6033
|
+
);
|
|
5932
6034
|
}
|
|
5933
|
-
if (
|
|
5934
|
-
throw new Error(
|
|
6035
|
+
if (functionItem.result === void 0 || functionItem.result === null) {
|
|
6036
|
+
throw new Error(
|
|
6037
|
+
`Function message must have a result, received: ${value(functionItem.result)}`
|
|
6038
|
+
);
|
|
5935
6039
|
}
|
|
5936
|
-
if (typeof
|
|
5937
|
-
throw new Error(
|
|
6040
|
+
if (typeof functionItem.result !== "string") {
|
|
6041
|
+
throw new Error(
|
|
6042
|
+
`Function message result must be a string, received: ${value(functionItem.result)}`
|
|
6043
|
+
);
|
|
5938
6044
|
}
|
|
5939
6045
|
break;
|
|
6046
|
+
}
|
|
5940
6047
|
default:
|
|
5941
|
-
throw new Error(
|
|
5942
|
-
`Unsupported message role: ${item.role}`
|
|
5943
|
-
);
|
|
6048
|
+
throw new Error(`Unsupported message role: ${value(role)}`);
|
|
5944
6049
|
}
|
|
5945
6050
|
}
|
|
5946
6051
|
function axValidateChatResponseResult(results) {
|
|
6052
|
+
const value = (v) => JSON.stringify(v, null, 2);
|
|
5947
6053
|
const resultsArray = Array.isArray(results) ? results : [results];
|
|
5948
6054
|
if (resultsArray.length === 0) {
|
|
5949
|
-
throw new Error(
|
|
6055
|
+
throw new Error(
|
|
6056
|
+
`Chat response results cannot be empty, received: ${value(resultsArray)}`
|
|
6057
|
+
);
|
|
5950
6058
|
}
|
|
5951
6059
|
for (let arrayIndex = 0; arrayIndex < resultsArray.length; arrayIndex++) {
|
|
5952
6060
|
const result = resultsArray[arrayIndex];
|
|
5953
6061
|
if (!result) {
|
|
5954
6062
|
throw new Error(
|
|
5955
|
-
`Chat response result at index ${arrayIndex} cannot be null or undefined`
|
|
6063
|
+
`Chat response result at index ${arrayIndex} cannot be null or undefined, received: ${value(result)}`
|
|
5956
6064
|
);
|
|
5957
6065
|
}
|
|
5958
6066
|
if (typeof result.index !== "number") {
|
|
5959
6067
|
throw new Error(
|
|
5960
|
-
`Chat response result at index ${arrayIndex} must have a numeric index`
|
|
6068
|
+
`Chat response result at index ${arrayIndex} must have a numeric index, received: ${value(result.index)}`
|
|
5961
6069
|
);
|
|
5962
6070
|
}
|
|
5963
6071
|
if (result.index < 0) {
|
|
5964
6072
|
throw new Error(
|
|
5965
|
-
`Chat response result at index ${arrayIndex} must have a non-negative index`
|
|
6073
|
+
`Chat response result at index ${arrayIndex} must have a non-negative index, received: ${value(result.index)}`
|
|
5966
6074
|
);
|
|
5967
6075
|
}
|
|
5968
6076
|
if (!result.content && !result.thought && !result.functionCalls && !result.finishReason) {
|
|
5969
6077
|
throw new Error(
|
|
5970
|
-
`Chat response result at index ${arrayIndex} must have at least one of: content, thought, functionCalls, or finishReason`
|
|
6078
|
+
`Chat response result at index ${arrayIndex} must have at least one of: content, thought, functionCalls, or finishReason, received: ${value({ content: result.content, thought: result.thought, functionCalls: result.functionCalls, finishReason: result.finishReason })}`
|
|
5971
6079
|
);
|
|
5972
6080
|
}
|
|
5973
6081
|
if (result.content !== void 0 && typeof result.content !== "string") {
|
|
5974
6082
|
throw new Error(
|
|
5975
|
-
`Chat response result content at index ${arrayIndex} must be a string`
|
|
6083
|
+
`Chat response result content at index ${arrayIndex} must be a string, received: ${value(result.content)}`
|
|
5976
6084
|
);
|
|
5977
6085
|
}
|
|
5978
6086
|
if (result.thought !== void 0 && typeof result.thought !== "string") {
|
|
5979
6087
|
throw new Error(
|
|
5980
|
-
`Chat response result thought at index ${arrayIndex} must be a string`
|
|
6088
|
+
`Chat response result thought at index ${arrayIndex} must be a string, received: ${value(result.thought)}`
|
|
5981
6089
|
);
|
|
5982
6090
|
}
|
|
5983
6091
|
if (result.name !== void 0) {
|
|
5984
6092
|
if (typeof result.name !== "string") {
|
|
5985
6093
|
throw new Error(
|
|
5986
|
-
`Chat response result name at index ${arrayIndex} must be a string`
|
|
6094
|
+
`Chat response result name at index ${arrayIndex} must be a string, received: ${value(result.name)}`
|
|
5987
6095
|
);
|
|
5988
6096
|
}
|
|
5989
6097
|
if (result.name.trim() === "") {
|
|
5990
6098
|
throw new Error(
|
|
5991
|
-
`Chat response result name at index ${arrayIndex} cannot be empty or whitespace-only`
|
|
6099
|
+
`Chat response result name at index ${arrayIndex} cannot be empty or whitespace-only, received: ${value(result.name)}`
|
|
5992
6100
|
);
|
|
5993
6101
|
}
|
|
5994
6102
|
}
|
|
6103
|
+
if (result.annotations !== void 0) {
|
|
6104
|
+
if (!Array.isArray(result.annotations)) {
|
|
6105
|
+
throw new Error(
|
|
6106
|
+
`Chat response result annotations at index ${arrayIndex} must be an array, received: ${value(result.annotations)}`
|
|
6107
|
+
);
|
|
6108
|
+
}
|
|
6109
|
+
for (let i = 0; i < result.annotations.length; i++) {
|
|
6110
|
+
const annotation = result.annotations[i];
|
|
6111
|
+
if (!annotation || typeof annotation !== "object") {
|
|
6112
|
+
throw new Error(
|
|
6113
|
+
`Chat response result annotation at index ${arrayIndex}[${i}] must be an object, received: ${value(annotation)}`
|
|
6114
|
+
);
|
|
6115
|
+
}
|
|
6116
|
+
if (annotation.type !== "url_citation") {
|
|
6117
|
+
throw new Error(
|
|
6118
|
+
`Chat response result annotation at index ${arrayIndex}[${i}] must have type 'url_citation', received: ${value(annotation.type)}`
|
|
6119
|
+
);
|
|
6120
|
+
}
|
|
6121
|
+
if (!annotation.url_citation || typeof annotation.url_citation !== "object") {
|
|
6122
|
+
throw new Error(
|
|
6123
|
+
`Chat response result annotation at index ${arrayIndex}[${i}] must have a valid url_citation object, received: ${value(annotation.url_citation)}`
|
|
6124
|
+
);
|
|
6125
|
+
}
|
|
6126
|
+
if (typeof annotation.url_citation.url !== "string") {
|
|
6127
|
+
throw new Error(
|
|
6128
|
+
`Chat response result annotation at index ${arrayIndex}[${i}] url_citation.url must be a string, received: ${value(annotation.url_citation.url)}`
|
|
6129
|
+
);
|
|
6130
|
+
}
|
|
6131
|
+
}
|
|
6132
|
+
}
|
|
5995
6133
|
if (result.id !== void 0) {
|
|
5996
6134
|
if (typeof result.id !== "string") {
|
|
5997
6135
|
throw new Error(
|
|
5998
|
-
`Chat response result id at index ${arrayIndex} must be a string`
|
|
6136
|
+
`Chat response result id at index ${arrayIndex} must be a string, received: ${value(result.id)}`
|
|
5999
6137
|
);
|
|
6000
6138
|
}
|
|
6001
6139
|
if (result.id.trim() === "") {
|
|
6002
6140
|
throw new Error(
|
|
6003
|
-
`Chat response result id at index ${arrayIndex} cannot be empty or whitespace-only`
|
|
6141
|
+
`Chat response result id at index ${arrayIndex} cannot be empty or whitespace-only, received: ${value(result.id)}`
|
|
6004
6142
|
);
|
|
6005
6143
|
}
|
|
6006
6144
|
}
|
|
6007
6145
|
if (result.functionCalls !== void 0) {
|
|
6008
6146
|
if (!Array.isArray(result.functionCalls)) {
|
|
6009
6147
|
throw new Error(
|
|
6010
|
-
`Chat response result functionCalls at index ${arrayIndex} must be an array`
|
|
6148
|
+
`Chat response result functionCalls at index ${arrayIndex} must be an array, received: ${value(result.functionCalls)}`
|
|
6011
6149
|
);
|
|
6012
6150
|
}
|
|
6013
6151
|
for (let callIndex = 0; callIndex < result.functionCalls.length; callIndex++) {
|
|
6014
6152
|
const functionCall = result.functionCalls[callIndex];
|
|
6015
6153
|
if (!functionCall) {
|
|
6016
6154
|
throw new Error(
|
|
6017
|
-
`Function call at index ${callIndex} in result ${arrayIndex} cannot be null or undefined`
|
|
6155
|
+
`Function call at index ${callIndex} in result ${arrayIndex} cannot be null or undefined, received: ${value(functionCall)}`
|
|
6018
6156
|
);
|
|
6019
6157
|
}
|
|
6020
6158
|
if (!functionCall.id || typeof functionCall.id !== "string" || functionCall.id.trim() === "") {
|
|
6021
6159
|
throw new Error(
|
|
6022
|
-
`Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty string id`
|
|
6160
|
+
`Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty string id, received: ${value(functionCall.id)}`
|
|
6023
6161
|
);
|
|
6024
6162
|
}
|
|
6025
6163
|
if (functionCall.type !== "function") {
|
|
6026
6164
|
throw new Error(
|
|
6027
|
-
`Function call at index ${callIndex} in result ${arrayIndex} must have type 'function'`
|
|
6165
|
+
`Function call at index ${callIndex} in result ${arrayIndex} must have type 'function', received: ${value(functionCall.type)}`
|
|
6028
6166
|
);
|
|
6029
6167
|
}
|
|
6030
6168
|
if (!functionCall.function) {
|
|
6031
6169
|
throw new Error(
|
|
6032
|
-
`Function call at index ${callIndex} in result ${arrayIndex} must have a function object`
|
|
6170
|
+
`Function call at index ${callIndex} in result ${arrayIndex} must have a function object, received: ${value(functionCall.function)}`
|
|
6033
6171
|
);
|
|
6034
6172
|
}
|
|
6035
6173
|
if (!functionCall.function.name || typeof functionCall.function.name !== "string" || functionCall.function.name.trim() === "") {
|
|
6036
6174
|
throw new Error(
|
|
6037
|
-
`Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty function name`
|
|
6175
|
+
`Function call at index ${callIndex} in result ${arrayIndex} must have a non-empty function name, received: ${value(functionCall.function.name)}`
|
|
6038
6176
|
);
|
|
6039
6177
|
}
|
|
6040
6178
|
if (functionCall.function.params !== void 0) {
|
|
6041
6179
|
if (typeof functionCall.function.params !== "string" && typeof functionCall.function.params !== "object") {
|
|
6042
6180
|
throw new Error(
|
|
6043
|
-
`Function call params at index ${callIndex} in result ${arrayIndex} must be a string or object`
|
|
6181
|
+
`Function call params at index ${callIndex} in result ${arrayIndex} must be a string or object, received: ${value(functionCall.function.params)}`
|
|
6044
6182
|
);
|
|
6045
6183
|
}
|
|
6046
6184
|
}
|
|
@@ -6056,7 +6194,7 @@ function axValidateChatResponseResult(results) {
|
|
|
6056
6194
|
];
|
|
6057
6195
|
if (!validFinishReasons.includes(result.finishReason)) {
|
|
6058
6196
|
throw new Error(
|
|
6059
|
-
`Chat response result finishReason at index ${arrayIndex} must be one of: ${validFinishReasons.join(", ")}`
|
|
6197
|
+
`Chat response result finishReason at index ${arrayIndex} must be one of: ${validFinishReasons.join(", ")}, received: ${value(result.finishReason)}`
|
|
6060
6198
|
);
|
|
6061
6199
|
}
|
|
6062
6200
|
}
|
|
@@ -6124,9 +6262,10 @@ var MemoryImpl = class {
|
|
|
6124
6262
|
}
|
|
6125
6263
|
}
|
|
6126
6264
|
};
|
|
6127
|
-
if (!lastItem || lastItem.role !== "assistant") {
|
|
6265
|
+
if (!lastItem || lastItem.role !== "assistant" || lastItem.role === "assistant" && !lastItem.updatable) {
|
|
6128
6266
|
this.data.push({
|
|
6129
6267
|
role: "assistant",
|
|
6268
|
+
updatable: true,
|
|
6130
6269
|
chat: [
|
|
6131
6270
|
{ index, value: structuredClone({ content, name, functionCalls }) }
|
|
6132
6271
|
]
|
|
@@ -6143,13 +6282,16 @@ var MemoryImpl = class {
|
|
|
6143
6282
|
log();
|
|
6144
6283
|
return;
|
|
6145
6284
|
}
|
|
6146
|
-
if (
|
|
6285
|
+
if (typeof content === "string" && content.trim() !== "") {
|
|
6286
|
+
;
|
|
6147
6287
|
chat.value.content = content;
|
|
6148
6288
|
}
|
|
6149
|
-
if (
|
|
6289
|
+
if (typeof name === "string" && name.trim() !== "") {
|
|
6290
|
+
;
|
|
6150
6291
|
chat.value.name = name;
|
|
6151
6292
|
}
|
|
6152
|
-
if (
|
|
6293
|
+
if (Array.isArray(functionCalls) && functionCalls.length > 0) {
|
|
6294
|
+
;
|
|
6153
6295
|
chat.value.functionCalls = functionCalls;
|
|
6154
6296
|
}
|
|
6155
6297
|
log();
|
|
@@ -16109,6 +16251,198 @@ var AxEvalUtil = {
|
|
|
16109
16251
|
novelF1ScoreOptimized
|
|
16110
16252
|
};
|
|
16111
16253
|
|
|
16254
|
+
// flow/flow.ts
|
|
16255
|
+
var AxFlow = class extends AxProgramWithSignature {
|
|
16256
|
+
nodes = /* @__PURE__ */ new Map();
|
|
16257
|
+
flowDefinition = [];
|
|
16258
|
+
nodeGenerators = /* @__PURE__ */ new Map();
|
|
16259
|
+
loopStack = [];
|
|
16260
|
+
constructor(signature = "userInput:string -> flowOutput:string") {
|
|
16261
|
+
super(signature);
|
|
16262
|
+
}
|
|
16263
|
+
/**
|
|
16264
|
+
* Declares a reusable computational node and its input/output signature.
|
|
16265
|
+
*
|
|
16266
|
+
* @param name - The name of the node
|
|
16267
|
+
* @param signature - An object where the key is a string representation of inputs
|
|
16268
|
+
* and the value is an object representing outputs
|
|
16269
|
+
* @returns this (for chaining)
|
|
16270
|
+
*
|
|
16271
|
+
* @example
|
|
16272
|
+
* ```typescript
|
|
16273
|
+
* flow.node('summarizer', { 'text:string': { summary: f.string() } })
|
|
16274
|
+
* ```
|
|
16275
|
+
*/
|
|
16276
|
+
node(name, signature) {
|
|
16277
|
+
const [inputSignature, outputSignature] = Object.entries(signature)[0] ?? [
|
|
16278
|
+
"",
|
|
16279
|
+
{}
|
|
16280
|
+
];
|
|
16281
|
+
if (!inputSignature || !outputSignature) {
|
|
16282
|
+
throw new Error(
|
|
16283
|
+
`Invalid signature for node '${name}': signature must have at least one input->output mapping`
|
|
16284
|
+
);
|
|
16285
|
+
}
|
|
16286
|
+
const outputFields = Object.entries(outputSignature).map(([key, value]) => {
|
|
16287
|
+
if (typeof value === "object" && value !== null && "type" in value) {
|
|
16288
|
+
const fieldType = value;
|
|
16289
|
+
let fieldString = `${key}:`;
|
|
16290
|
+
if (fieldType.isOptional) {
|
|
16291
|
+
const colonIndex = fieldString.lastIndexOf(":");
|
|
16292
|
+
fieldString = fieldString.slice(0, colonIndex) + "?" + fieldString.slice(colonIndex);
|
|
16293
|
+
}
|
|
16294
|
+
if (fieldType.isInternal) {
|
|
16295
|
+
const colonIndex = fieldString.lastIndexOf(":");
|
|
16296
|
+
fieldString = fieldString.slice(0, colonIndex) + "!" + fieldString.slice(colonIndex);
|
|
16297
|
+
}
|
|
16298
|
+
fieldString += fieldType.type;
|
|
16299
|
+
if (fieldType.isArray) {
|
|
16300
|
+
fieldString += "[]";
|
|
16301
|
+
}
|
|
16302
|
+
if (fieldType.type === "class" && fieldType.options) {
|
|
16303
|
+
fieldString += ` "${fieldType.options.join(", ")}"`;
|
|
16304
|
+
}
|
|
16305
|
+
if (fieldType.description && (fieldType.type !== "class" || !fieldType.options)) {
|
|
16306
|
+
fieldString += ` "${fieldType.description}"`;
|
|
16307
|
+
}
|
|
16308
|
+
return fieldString;
|
|
16309
|
+
}
|
|
16310
|
+
return `${key}:string`;
|
|
16311
|
+
}).join(", ");
|
|
16312
|
+
const signatureString = `${inputSignature} -> ${outputFields}`;
|
|
16313
|
+
this.nodes.set(name, {
|
|
16314
|
+
inputs: { [inputSignature]: true },
|
|
16315
|
+
outputs: outputSignature
|
|
16316
|
+
});
|
|
16317
|
+
this.nodeGenerators.set(name, new AxGen(signatureString));
|
|
16318
|
+
return this;
|
|
16319
|
+
}
|
|
16320
|
+
/**
|
|
16321
|
+
* Applies a synchronous transformation to the state object.
|
|
16322
|
+
*
|
|
16323
|
+
* @param transform - Function that takes the current state and returns a new state
|
|
16324
|
+
* @returns this (for chaining)
|
|
16325
|
+
*
|
|
16326
|
+
* @example
|
|
16327
|
+
* ```typescript
|
|
16328
|
+
* flow.map(state => ({ ...state, processedText: state.text.toLowerCase() }))
|
|
16329
|
+
* ```
|
|
16330
|
+
*/
|
|
16331
|
+
map(transform) {
|
|
16332
|
+
this.flowDefinition.push((state) => {
|
|
16333
|
+
return transform(state);
|
|
16334
|
+
});
|
|
16335
|
+
return this;
|
|
16336
|
+
}
|
|
16337
|
+
/**
|
|
16338
|
+
* Executes a previously defined node.
|
|
16339
|
+
*
|
|
16340
|
+
* @param nodeName - The name of the node to execute (must exist in the nodes map)
|
|
16341
|
+
* @param mapping - Function that takes the current state and returns the input object required by the node
|
|
16342
|
+
* @param dynamicContext - Optional object to override the AI service or options for this specific step
|
|
16343
|
+
* @returns this (for chaining)
|
|
16344
|
+
*
|
|
16345
|
+
* @example
|
|
16346
|
+
* ```typescript
|
|
16347
|
+
* flow.execute('summarizer', state => ({ text: state.originalText }), { ai: cheapAI })
|
|
16348
|
+
* ```
|
|
16349
|
+
*/
|
|
16350
|
+
execute(nodeName, mapping, dynamicContext) {
|
|
16351
|
+
if (!this.nodes.has(nodeName)) {
|
|
16352
|
+
throw new Error(
|
|
16353
|
+
`Node '${nodeName}' not found. Make sure to define it with .node() first.`
|
|
16354
|
+
);
|
|
16355
|
+
}
|
|
16356
|
+
const nodeGenerator = this.nodeGenerators.get(nodeName);
|
|
16357
|
+
if (!nodeGenerator) {
|
|
16358
|
+
throw new Error(`Node generator for '${nodeName}' not found.`);
|
|
16359
|
+
}
|
|
16360
|
+
this.flowDefinition.push(async (state, context3) => {
|
|
16361
|
+
const ai = dynamicContext?.ai ?? context3.mainAi;
|
|
16362
|
+
const options = dynamicContext?.options ?? context3.mainOptions;
|
|
16363
|
+
const nodeInputs = mapping(state);
|
|
16364
|
+
const result = await nodeGenerator.forward(ai, nodeInputs, options);
|
|
16365
|
+
return {
|
|
16366
|
+
...state,
|
|
16367
|
+
[`${nodeName}Result`]: result
|
|
16368
|
+
};
|
|
16369
|
+
});
|
|
16370
|
+
return this;
|
|
16371
|
+
}
|
|
16372
|
+
/**
|
|
16373
|
+
* Marks the beginning of a loop block.
|
|
16374
|
+
*
|
|
16375
|
+
* @param condition - Function that takes the current state and returns a boolean
|
|
16376
|
+
* @returns this (for chaining)
|
|
16377
|
+
*
|
|
16378
|
+
* @example
|
|
16379
|
+
* ```typescript
|
|
16380
|
+
* flow.while(state => state.iterations < 3)
|
|
16381
|
+
* .map(state => ({ ...state, iterations: (state.iterations || 0) + 1 }))
|
|
16382
|
+
* .endWhile()
|
|
16383
|
+
* ```
|
|
16384
|
+
*/
|
|
16385
|
+
while(condition) {
|
|
16386
|
+
const loopStartIndex = this.flowDefinition.length;
|
|
16387
|
+
this.loopStack.push(loopStartIndex);
|
|
16388
|
+
const placeholderStep = Object.assign(
|
|
16389
|
+
(state) => state,
|
|
16390
|
+
{
|
|
16391
|
+
_condition: condition,
|
|
16392
|
+
_isLoopStart: true
|
|
16393
|
+
}
|
|
16394
|
+
);
|
|
16395
|
+
this.flowDefinition.push(placeholderStep);
|
|
16396
|
+
return this;
|
|
16397
|
+
}
|
|
16398
|
+
/**
|
|
16399
|
+
* Marks the end of a loop block.
|
|
16400
|
+
*
|
|
16401
|
+
* @returns this (for chaining)
|
|
16402
|
+
*/
|
|
16403
|
+
endWhile() {
|
|
16404
|
+
if (this.loopStack.length === 0) {
|
|
16405
|
+
throw new Error("endWhile() called without matching while()");
|
|
16406
|
+
}
|
|
16407
|
+
const loopStartIndex = this.loopStack.pop();
|
|
16408
|
+
const placeholderStep = this.flowDefinition[loopStartIndex];
|
|
16409
|
+
if (!placeholderStep || !("_isLoopStart" in placeholderStep)) {
|
|
16410
|
+
throw new Error("Loop start step not found or invalid");
|
|
16411
|
+
}
|
|
16412
|
+
const condition = placeholderStep._condition;
|
|
16413
|
+
const loopBodySteps = this.flowDefinition.splice(loopStartIndex + 1);
|
|
16414
|
+
this.flowDefinition[loopStartIndex] = async (state, context3) => {
|
|
16415
|
+
let currentState = state;
|
|
16416
|
+
while (condition(currentState)) {
|
|
16417
|
+
for (const step of loopBodySteps) {
|
|
16418
|
+
currentState = await step(currentState, context3);
|
|
16419
|
+
}
|
|
16420
|
+
}
|
|
16421
|
+
return currentState;
|
|
16422
|
+
};
|
|
16423
|
+
return this;
|
|
16424
|
+
}
|
|
16425
|
+
/**
|
|
16426
|
+
* Executes the flow with the given AI service and input values.
|
|
16427
|
+
*
|
|
16428
|
+
* @param ai - The AI service to use as the default for all steps
|
|
16429
|
+
* @param values - The input values for the flow
|
|
16430
|
+
* @param options - Optional forward options to use as defaults
|
|
16431
|
+
* @returns Promise that resolves to the final output
|
|
16432
|
+
*/
|
|
16433
|
+
async forward(ai, values, options) {
|
|
16434
|
+
let state = { ...values };
|
|
16435
|
+
const context3 = {
|
|
16436
|
+
mainAi: ai,
|
|
16437
|
+
mainOptions: options
|
|
16438
|
+
};
|
|
16439
|
+
for (const step of this.flowDefinition) {
|
|
16440
|
+
state = await step(state, context3);
|
|
16441
|
+
}
|
|
16442
|
+
return state;
|
|
16443
|
+
}
|
|
16444
|
+
};
|
|
16445
|
+
|
|
16112
16446
|
// ../../node_modules/uuid/dist/esm-node/rng.js
|
|
16113
16447
|
import crypto4 from "crypto";
|
|
16114
16448
|
var rnds8Pool = new Uint8Array(256);
|
|
@@ -16645,6 +16979,7 @@ export {
|
|
|
16645
16979
|
AxAIOpenAIResponsesBase,
|
|
16646
16980
|
AxAIOpenAIResponsesImpl,
|
|
16647
16981
|
AxAIOpenAIResponsesModel,
|
|
16982
|
+
AxAIRefusalError,
|
|
16648
16983
|
AxAIReka,
|
|
16649
16984
|
AxAIRekaModel,
|
|
16650
16985
|
AxAIServiceAbortedError,
|
|
@@ -16676,6 +17011,7 @@ export {
|
|
|
16676
17011
|
AxDockerSession,
|
|
16677
17012
|
AxEmbeddingAdapter,
|
|
16678
17013
|
AxEvalUtil,
|
|
17014
|
+
AxFlow,
|
|
16679
17015
|
AxFunctionError,
|
|
16680
17016
|
AxFunctionProcessor,
|
|
16681
17017
|
AxGen,
|