@igniter-js/agents 0.1.13 → 0.1.14
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/AGENTS.md +115 -54
- package/README.md +72 -42
- package/dist/adapters/index.d.mts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/{index-CX4IgrRt.d.mts → index-CqUbHeyY.d.mts} +78 -2
- package/dist/{index-CX4IgrRt.d.ts → index-CqUbHeyY.d.ts} +78 -2
- package/dist/index.d.mts +446 -53
- package/dist/index.d.ts +446 -53
- package/dist/index.js +717 -340
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +717 -341
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var common = require('@igniter-js/common');
|
|
4
4
|
var mcp = require('@ai-sdk/mcp');
|
|
5
5
|
var stdio_js = require('@modelcontextprotocol/sdk/client/stdio.js');
|
|
6
6
|
var streamableHttp_js = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
7
7
|
var ai = require('ai');
|
|
8
|
+
var zod = require('zod');
|
|
8
9
|
var promises = require('fs/promises');
|
|
9
10
|
var path = require('path');
|
|
10
11
|
|
|
@@ -32,7 +33,7 @@ var IgniterAgentErrorCode = /* @__PURE__ */ ((IgniterAgentErrorCode3) => {
|
|
|
32
33
|
IgniterAgentErrorCode3["ADAPTER_NOT_INITIALIZED"] = "IGNITER_AGENT_ADAPTER_NOT_INITIALIZED";
|
|
33
34
|
return IgniterAgentErrorCode3;
|
|
34
35
|
})(IgniterAgentErrorCode || {});
|
|
35
|
-
var IgniterAgentError = class extends
|
|
36
|
+
var IgniterAgentError = class extends common.IgniterError {
|
|
36
37
|
/**
|
|
37
38
|
* Creates a new IgniterAgentError.
|
|
38
39
|
*
|
|
@@ -388,7 +389,12 @@ var IgniterAgentManagerCore = class _IgniterAgentManagerCore {
|
|
|
388
389
|
* @example
|
|
389
390
|
* ```typescript
|
|
390
391
|
* const agent = manager.get('support');
|
|
391
|
-
* const response = await agent.generate({
|
|
392
|
+
* const response = await agent.generate({
|
|
393
|
+
* chatId: 'chat_123',
|
|
394
|
+
* userId: 'user_123',
|
|
395
|
+
* context: {},
|
|
396
|
+
* message: { role: 'user', content: 'Hello!' }
|
|
397
|
+
* });
|
|
392
398
|
* ```
|
|
393
399
|
*/
|
|
394
400
|
get(name) {
|
|
@@ -663,6 +669,244 @@ var IgniterAgentMemoryCore = class {
|
|
|
663
669
|
}
|
|
664
670
|
};
|
|
665
671
|
|
|
672
|
+
// src/utils/strings.ts
|
|
673
|
+
var IgniterAgentStringUtils = class {
|
|
674
|
+
/**
|
|
675
|
+
* Generates a unique identifier.
|
|
676
|
+
*/
|
|
677
|
+
static generateId(prefix) {
|
|
678
|
+
const random = Math.random().toString(36).substring(2, 12);
|
|
679
|
+
return prefix ? `${prefix}_${random}` : random;
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Truncates a string to a maximum length.
|
|
683
|
+
*/
|
|
684
|
+
static truncate(str, maxLength, suffix = "...") {
|
|
685
|
+
if (str.length <= maxLength) return str;
|
|
686
|
+
return str.slice(0, maxLength - suffix.length) + suffix;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Converts a string to snake_case.
|
|
690
|
+
*/
|
|
691
|
+
static toSnakeCase(str) {
|
|
692
|
+
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Converts a string to camelCase.
|
|
696
|
+
*/
|
|
697
|
+
static toCamelCase(str) {
|
|
698
|
+
return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^(.)/, (char) => char.toLowerCase());
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
// src/utils/objects.ts
|
|
703
|
+
var IgniterAgentObjectUtils = class _IgniterAgentObjectUtils {
|
|
704
|
+
/**
|
|
705
|
+
* Deep merges two objects.
|
|
706
|
+
*/
|
|
707
|
+
static deepMerge(target, source) {
|
|
708
|
+
const result = { ...target };
|
|
709
|
+
for (const key in source) {
|
|
710
|
+
const sourceValue = source[key];
|
|
711
|
+
const targetValue = target[key];
|
|
712
|
+
if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
713
|
+
result[key] = _IgniterAgentObjectUtils.deepMerge(
|
|
714
|
+
targetValue,
|
|
715
|
+
sourceValue
|
|
716
|
+
);
|
|
717
|
+
} else {
|
|
718
|
+
result[key] = sourceValue;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
return result;
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Picks specified keys from an object.
|
|
725
|
+
*/
|
|
726
|
+
static pick(obj, keys) {
|
|
727
|
+
const result = {};
|
|
728
|
+
for (const key of keys) {
|
|
729
|
+
if (key in obj) {
|
|
730
|
+
result[key] = obj[key];
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return result;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Omits specified keys from an object.
|
|
737
|
+
*/
|
|
738
|
+
static omit(obj, keys) {
|
|
739
|
+
const result = { ...obj };
|
|
740
|
+
for (const key of keys) {
|
|
741
|
+
delete result[key];
|
|
742
|
+
}
|
|
743
|
+
return result;
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
// src/utils/async.ts
|
|
748
|
+
var IgniterAgentAsyncUtils = class _IgniterAgentAsyncUtils {
|
|
749
|
+
/**
|
|
750
|
+
* Delays execution for a specified duration.
|
|
751
|
+
*/
|
|
752
|
+
static delay(ms) {
|
|
753
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Retries an async function with exponential backoff.
|
|
757
|
+
*/
|
|
758
|
+
static async retry(fn, options = {}) {
|
|
759
|
+
const {
|
|
760
|
+
maxAttempts = 3,
|
|
761
|
+
baseDelay = 1e3,
|
|
762
|
+
maxDelay = 3e4,
|
|
763
|
+
onRetry
|
|
764
|
+
} = options;
|
|
765
|
+
let lastError;
|
|
766
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
767
|
+
try {
|
|
768
|
+
return await fn();
|
|
769
|
+
} catch (error) {
|
|
770
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
771
|
+
if (attempt === maxAttempts) {
|
|
772
|
+
throw lastError;
|
|
773
|
+
}
|
|
774
|
+
onRetry?.(attempt, lastError);
|
|
775
|
+
const delayMs = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
|
|
776
|
+
await _IgniterAgentAsyncUtils.delay(delayMs);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
throw lastError;
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
// src/utils/validation.ts
|
|
784
|
+
var IgniterAgentValidationUtils = class {
|
|
785
|
+
/**
|
|
786
|
+
* Checks if a value is defined (not null or undefined).
|
|
787
|
+
*/
|
|
788
|
+
static isDefined(value) {
|
|
789
|
+
return value !== null && value !== void 0;
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Checks if a value is a non-empty string.
|
|
793
|
+
*/
|
|
794
|
+
static isNonEmptyString(value) {
|
|
795
|
+
return typeof value === "string" && value.length > 0;
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Checks if a value is a plain object.
|
|
799
|
+
*/
|
|
800
|
+
static isPlainObject(value) {
|
|
801
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
// src/utils/context.ts
|
|
806
|
+
var IgniterAgentContext = class {
|
|
807
|
+
/**
|
|
808
|
+
* Private constructor to prevent instantiation.
|
|
809
|
+
* This is a static-only utility class.
|
|
810
|
+
*/
|
|
811
|
+
constructor() {
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Creates an execution context to pass to AI SDK's experimental_context.
|
|
815
|
+
*
|
|
816
|
+
* Your context object is spread at the top level, merged with writer and metadata.
|
|
817
|
+
* This means you can access your fields directly without a wrapper.
|
|
818
|
+
*
|
|
819
|
+
* @template TContext - Your custom context type (must be an object)
|
|
820
|
+
* @param options - The context creation options
|
|
821
|
+
* @returns The merged execution context ready for AI SDK
|
|
822
|
+
*
|
|
823
|
+
* @example Basic usage
|
|
824
|
+
* ```typescript
|
|
825
|
+
* const context = IgniterAgentContext.create({
|
|
826
|
+
* context: { userId: '123', db: database, permissions: ['read', 'write'] },
|
|
827
|
+
* writer: streamWriter
|
|
828
|
+
* });
|
|
829
|
+
* // Access in tools: executionOptions.experimental_context.userId
|
|
830
|
+
* ```
|
|
831
|
+
*
|
|
832
|
+
* @example With typed context
|
|
833
|
+
* ```typescript
|
|
834
|
+
* interface MyAppContext {
|
|
835
|
+
* tenant: string;
|
|
836
|
+
* workspace: string;
|
|
837
|
+
* features: string[];
|
|
838
|
+
* }
|
|
839
|
+
*
|
|
840
|
+
* const context = IgniterAgentContext.create<MyAppContext>({
|
|
841
|
+
* context: { tenant: 'acme', workspace: 'main', features: ['analytics'] },
|
|
842
|
+
* writer: streamWriter
|
|
843
|
+
* });
|
|
844
|
+
* // Access in tools: executionOptions.experimental_context.tenant
|
|
845
|
+
* ```
|
|
846
|
+
*
|
|
847
|
+
* @example With metadata for tracing
|
|
848
|
+
* ```typescript
|
|
849
|
+
* const context = IgniterAgentContext.create({
|
|
850
|
+
* context: { userId: '123', tenantId: 'acme' },
|
|
851
|
+
* writer: streamWriter,
|
|
852
|
+
* metadata: { agent: 'reports', requestId: 'req_123' }
|
|
853
|
+
* });
|
|
854
|
+
* ```
|
|
855
|
+
*/
|
|
856
|
+
static create(options) {
|
|
857
|
+
return {
|
|
858
|
+
...options.context,
|
|
859
|
+
writer: options.writer,
|
|
860
|
+
metadata: {
|
|
861
|
+
startTime: /* @__PURE__ */ new Date(),
|
|
862
|
+
...options.metadata
|
|
863
|
+
}
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Gets your custom context from execution options.
|
|
868
|
+
*
|
|
869
|
+
* Your context fields are available directly in experimental_context (no wrapper).
|
|
870
|
+
* This helper provides type-safe access.
|
|
871
|
+
*
|
|
872
|
+
* @template T - Your custom context type (object)
|
|
873
|
+
* @param executionOptions - Tool execution options from AI SDK
|
|
874
|
+
* @returns Your custom context or undefined if not available
|
|
875
|
+
*
|
|
876
|
+
* @example Direct access (no helper needed)
|
|
877
|
+
* ```typescript
|
|
878
|
+
* export const myTool = tool({
|
|
879
|
+
* execute: async (params, executionOptions) => {
|
|
880
|
+
* // Access fields directly
|
|
881
|
+
* const userId = executionOptions.experimental_context.userId;
|
|
882
|
+
* const db = executionOptions.experimental_context.db;
|
|
883
|
+
* }
|
|
884
|
+
* });
|
|
885
|
+
* ```
|
|
886
|
+
*
|
|
887
|
+
* @example With typed helper
|
|
888
|
+
* ```typescript
|
|
889
|
+
* interface AppContext {
|
|
890
|
+
* userId: string;
|
|
891
|
+
* tenantId: string;
|
|
892
|
+
* db: Database;
|
|
893
|
+
* }
|
|
894
|
+
*
|
|
895
|
+
* export const myTool = tool({
|
|
896
|
+
* execute: async (params, executionOptions) => {
|
|
897
|
+
* const ctx = IgniterAgentContext.get<AppContext>(executionOptions);
|
|
898
|
+
* if (ctx) {
|
|
899
|
+
* const user = await ctx.db.users.findOne(ctx.userId);
|
|
900
|
+
* }
|
|
901
|
+
* }
|
|
902
|
+
* });
|
|
903
|
+
* ```
|
|
904
|
+
*/
|
|
905
|
+
static get(executionOptions) {
|
|
906
|
+
return executionOptions?.experimental_context;
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
|
|
666
910
|
// src/core/agent.ts
|
|
667
911
|
var IgniterAgentCore = class {
|
|
668
912
|
constructor(agent) {
|
|
@@ -916,101 +1160,107 @@ var IgniterAgentCore = class {
|
|
|
916
1160
|
}
|
|
917
1161
|
}
|
|
918
1162
|
/**
|
|
919
|
-
* Generates a response
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
this.
|
|
930
|
-
|
|
931
|
-
|
|
1163
|
+
* Generates a response for the given message or messages.
|
|
1164
|
+
*
|
|
1165
|
+
* @description
|
|
1166
|
+
* Accepts either a single `message` or an array of `messages`.
|
|
1167
|
+
* When both are provided, `message` takes precedence.
|
|
1168
|
+
*
|
|
1169
|
+
* @param params - The parameters for the generate call.
|
|
1170
|
+
* @returns The generated response.
|
|
1171
|
+
*/
|
|
1172
|
+
async generate(params) {
|
|
1173
|
+
const { message, messages } = this.resolveMessageInput(params);
|
|
1174
|
+
const requestId = `req_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
1175
|
+
const historyMessages = await this.initializeChatMemory({
|
|
1176
|
+
chatId: params.chatId,
|
|
1177
|
+
userId: params.userId,
|
|
1178
|
+
agentId: this.getName(),
|
|
1179
|
+
message
|
|
932
1180
|
});
|
|
1181
|
+
const agent = this.prepare({
|
|
1182
|
+
chatId: params.chatId,
|
|
1183
|
+
userId: params.userId,
|
|
1184
|
+
agentId: this.getName(),
|
|
1185
|
+
message,
|
|
1186
|
+
requestId,
|
|
1187
|
+
context: params.context,
|
|
1188
|
+
streamed: false
|
|
1189
|
+
});
|
|
1190
|
+
const inputMessages = params.message ? [message] : messages;
|
|
1191
|
+
const resolvedMessages = historyMessages ? [...historyMessages, ...inputMessages] : inputMessages;
|
|
933
1192
|
try {
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
this.telemetry?.emit("igniter.agent.generation.generate.success", {
|
|
940
|
-
level: "debug",
|
|
941
|
-
attributes: {
|
|
942
|
-
...attributes,
|
|
943
|
-
"ctx.generation.durationMs": durationMs
|
|
944
|
-
}
|
|
1193
|
+
return await agent.generate({
|
|
1194
|
+
abortSignal: params.abortSignal,
|
|
1195
|
+
options: params.options,
|
|
1196
|
+
messages: resolvedMessages,
|
|
1197
|
+
prompt: params.prompt
|
|
945
1198
|
});
|
|
946
|
-
this.logger?.success?.("IgniterAgent.generate success", {
|
|
947
|
-
...attributes,
|
|
948
|
-
durationMs
|
|
949
|
-
});
|
|
950
|
-
return result;
|
|
951
1199
|
} catch (error) {
|
|
952
1200
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
953
1201
|
this.telemetry?.emit("igniter.agent.generation.generate.error", {
|
|
954
1202
|
level: "error",
|
|
955
1203
|
attributes: {
|
|
956
|
-
|
|
1204
|
+
"ctx.agent.name": this.getName(),
|
|
1205
|
+
"ctx.agent.chatId": params.chatId,
|
|
1206
|
+
"ctx.agent.userId": params.userId,
|
|
1207
|
+
"ctx.generation.streamed": false,
|
|
957
1208
|
...this.getErrorAttributes(err, "generation.generate")
|
|
958
1209
|
}
|
|
959
1210
|
});
|
|
960
|
-
this.logger?.error("IgniterAgent.generate failed", err);
|
|
961
1211
|
throw err;
|
|
962
1212
|
}
|
|
963
1213
|
}
|
|
964
1214
|
/**
|
|
965
|
-
* Streams a response
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
this.
|
|
976
|
-
|
|
977
|
-
|
|
1215
|
+
* Streams a response for the given message or messages.
|
|
1216
|
+
*
|
|
1217
|
+
* @description
|
|
1218
|
+
* Accepts either a single `message` or an array of `messages`.
|
|
1219
|
+
* When both are provided, `message` takes precedence.
|
|
1220
|
+
*
|
|
1221
|
+
* @param params - The parameters for the stream call.
|
|
1222
|
+
* @returns The streaming response.
|
|
1223
|
+
*/
|
|
1224
|
+
async stream(params) {
|
|
1225
|
+
const { message, messages } = this.resolveMessageInput(params);
|
|
1226
|
+
const requestId = `req_${Date.now()}_${Math.random().toString(36).substring(7)}`;
|
|
1227
|
+
const historyMessages = await this.initializeChatMemory({
|
|
1228
|
+
chatId: params.chatId,
|
|
1229
|
+
userId: params.userId,
|
|
1230
|
+
agentId: this.getName(),
|
|
1231
|
+
message
|
|
1232
|
+
});
|
|
1233
|
+
const agent = this.prepare({
|
|
1234
|
+
chatId: params.chatId,
|
|
1235
|
+
userId: params.userId,
|
|
1236
|
+
agentId: this.getName(),
|
|
1237
|
+
message,
|
|
1238
|
+
requestId,
|
|
1239
|
+
context: params.context,
|
|
1240
|
+
streamed: true
|
|
978
1241
|
});
|
|
1242
|
+
const inputMessages = params.message ? [message] : messages;
|
|
1243
|
+
const resolvedMessages = historyMessages ? [...historyMessages, ...inputMessages] : inputMessages;
|
|
979
1244
|
try {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
this.telemetry?.emit("igniter.agent.generation.stream.chunk", {
|
|
987
|
-
level: "debug",
|
|
988
|
-
attributes
|
|
989
|
-
});
|
|
990
|
-
};
|
|
991
|
-
const wrapped = this.wrapStreamResult(result, emitChunk);
|
|
992
|
-
this.telemetry?.emit("igniter.agent.generation.stream.success", {
|
|
993
|
-
level: "debug",
|
|
994
|
-
attributes: {
|
|
995
|
-
...attributes,
|
|
996
|
-
"ctx.generation.durationMs": durationMs
|
|
997
|
-
}
|
|
998
|
-
});
|
|
999
|
-
this.logger?.success?.("IgniterAgent.stream success", {
|
|
1000
|
-
...attributes,
|
|
1001
|
-
durationMs
|
|
1245
|
+
return await agent.stream({
|
|
1246
|
+
abortSignal: params.abortSignal,
|
|
1247
|
+
experimental_transform: params.experimental_transform,
|
|
1248
|
+
options: params.options,
|
|
1249
|
+
messages: resolvedMessages,
|
|
1250
|
+
prompt: params.prompt
|
|
1002
1251
|
});
|
|
1003
|
-
return wrapped;
|
|
1004
1252
|
} catch (error) {
|
|
1005
1253
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
1006
1254
|
this.telemetry?.emit("igniter.agent.generation.stream.error", {
|
|
1007
1255
|
level: "error",
|
|
1008
1256
|
attributes: {
|
|
1009
|
-
|
|
1257
|
+
"ctx.agent.name": this.getName(),
|
|
1258
|
+
"ctx.agent.chatId": params.chatId,
|
|
1259
|
+
"ctx.agent.userId": params.userId,
|
|
1260
|
+
"ctx.generation.streamed": true,
|
|
1010
1261
|
...this.getErrorAttributes(err, "generation.stream")
|
|
1011
1262
|
}
|
|
1012
1263
|
});
|
|
1013
|
-
this.logger?.error("IgniterAgent.stream failed", err);
|
|
1014
1264
|
throw err;
|
|
1015
1265
|
}
|
|
1016
1266
|
}
|
|
@@ -1042,109 +1292,16 @@ var IgniterAgentCore = class {
|
|
|
1042
1292
|
* Gets all registered tools from all toolsets.
|
|
1043
1293
|
*/
|
|
1044
1294
|
getTools() {
|
|
1045
|
-
const
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
allTools[toolName] = wrapped;
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1295
|
+
const allTools = this.initializeTools({
|
|
1296
|
+
chatId: "",
|
|
1297
|
+
userId: "",
|
|
1298
|
+
agentId: this.getName()
|
|
1299
|
+
});
|
|
1053
1300
|
return allTools;
|
|
1054
1301
|
}
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
}
|
|
1059
|
-
const execute = tool2.execute;
|
|
1060
|
-
const fullName = `${toolsetName}.${toolName}`;
|
|
1061
|
-
const agentName = this.getName();
|
|
1062
|
-
return {
|
|
1063
|
-
...tool2,
|
|
1064
|
-
execute: async (input, options) => {
|
|
1065
|
-
const startTime = Date.now();
|
|
1066
|
-
this.hooks.onToolCallStart?.(agentName, fullName, input);
|
|
1067
|
-
this.telemetry?.emit("igniter.agent.tool.execute.started", {
|
|
1068
|
-
level: "debug",
|
|
1069
|
-
attributes: {
|
|
1070
|
-
"ctx.agent.name": agentName,
|
|
1071
|
-
"ctx.tool.toolset": toolsetName,
|
|
1072
|
-
"ctx.tool.name": toolName,
|
|
1073
|
-
"ctx.tool.fullName": fullName
|
|
1074
|
-
}
|
|
1075
|
-
});
|
|
1076
|
-
this.logger?.debug("IgniterAgent.tool.execute started", {
|
|
1077
|
-
agent: agentName,
|
|
1078
|
-
tool: fullName
|
|
1079
|
-
});
|
|
1080
|
-
try {
|
|
1081
|
-
const result = await execute(input, options);
|
|
1082
|
-
const durationMs = Date.now() - startTime;
|
|
1083
|
-
this.hooks.onToolCallEnd?.(agentName, fullName, result);
|
|
1084
|
-
this.telemetry?.emit("igniter.agent.tool.execute.success", {
|
|
1085
|
-
level: "debug",
|
|
1086
|
-
attributes: {
|
|
1087
|
-
"ctx.agent.name": agentName,
|
|
1088
|
-
"ctx.tool.toolset": toolsetName,
|
|
1089
|
-
"ctx.tool.name": toolName,
|
|
1090
|
-
"ctx.tool.fullName": fullName,
|
|
1091
|
-
"ctx.tool.durationMs": durationMs
|
|
1092
|
-
}
|
|
1093
|
-
});
|
|
1094
|
-
this.logger?.success?.("IgniterAgent.tool.execute success", {
|
|
1095
|
-
agent: agentName,
|
|
1096
|
-
tool: fullName,
|
|
1097
|
-
durationMs
|
|
1098
|
-
});
|
|
1099
|
-
return result;
|
|
1100
|
-
} catch (error) {
|
|
1101
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
1102
|
-
this.hooks.onToolCallError?.(agentName, fullName, err);
|
|
1103
|
-
this.telemetry?.emit("igniter.agent.tool.execute.error", {
|
|
1104
|
-
level: "error",
|
|
1105
|
-
attributes: {
|
|
1106
|
-
"ctx.agent.name": agentName,
|
|
1107
|
-
"ctx.tool.toolset": toolsetName,
|
|
1108
|
-
"ctx.tool.name": toolName,
|
|
1109
|
-
"ctx.tool.fullName": fullName,
|
|
1110
|
-
...this.getErrorAttributes(err, "tool.execute")
|
|
1111
|
-
}
|
|
1112
|
-
});
|
|
1113
|
-
this.logger?.error("IgniterAgent.tool.execute failed", err);
|
|
1114
|
-
throw err;
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
};
|
|
1118
|
-
}
|
|
1119
|
-
wrapStreamResult(result, onChunk) {
|
|
1120
|
-
if (!result) {
|
|
1121
|
-
return result;
|
|
1122
|
-
}
|
|
1123
|
-
if (typeof result[Symbol.asyncIterator] === "function") {
|
|
1124
|
-
const iterable = result;
|
|
1125
|
-
return {
|
|
1126
|
-
[Symbol.asyncIterator]: async function* () {
|
|
1127
|
-
for await (const chunk of iterable) {
|
|
1128
|
-
onChunk();
|
|
1129
|
-
yield chunk;
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
|
-
const maybeTextStream = result.textStream;
|
|
1135
|
-
if (maybeTextStream && typeof maybeTextStream[Symbol.asyncIterator] === "function") {
|
|
1136
|
-
return {
|
|
1137
|
-
...result,
|
|
1138
|
-
textStream: (async function* () {
|
|
1139
|
-
for await (const chunk of maybeTextStream) {
|
|
1140
|
-
onChunk();
|
|
1141
|
-
yield chunk;
|
|
1142
|
-
}
|
|
1143
|
-
})()
|
|
1144
|
-
};
|
|
1145
|
-
}
|
|
1146
|
-
return result;
|
|
1147
|
-
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Gets error attributes for telemetry.
|
|
1304
|
+
*/
|
|
1148
1305
|
getErrorAttributes(error, operation) {
|
|
1149
1306
|
return {
|
|
1150
1307
|
"ctx.error.code": error.code ?? error.name ?? "IGNITER_AGENT_UNKNOWN_ERROR" /* UNKNOWN */,
|
|
@@ -1153,41 +1310,345 @@ var IgniterAgentCore = class {
|
|
|
1153
1310
|
"ctx.error.component": "agent"
|
|
1154
1311
|
};
|
|
1155
1312
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1313
|
+
/**
|
|
1314
|
+
* Gets an agent instance with the given context.
|
|
1315
|
+
*/
|
|
1316
|
+
prepare(params) {
|
|
1317
|
+
const tools = this.initializeTools({
|
|
1318
|
+
chatId: params.chatId,
|
|
1319
|
+
userId: params.userId,
|
|
1320
|
+
agentId: this._agent.name
|
|
1321
|
+
});
|
|
1158
1322
|
if (!this._agent.model) {
|
|
1159
1323
|
throw new IgniterAgentConfigError({
|
|
1160
1324
|
message: "Model is required. Call withModel() before build()",
|
|
1161
1325
|
field: "model"
|
|
1162
1326
|
});
|
|
1163
1327
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1328
|
+
return new ai.ToolLoopAgent({
|
|
1329
|
+
id: this._agent.name,
|
|
1330
|
+
model: this._agent.model,
|
|
1331
|
+
instructions: this._agent.instructions.getTemplate(),
|
|
1332
|
+
tools,
|
|
1333
|
+
callOptionsSchema: this._agent.schema,
|
|
1334
|
+
prepareCall: async (options) => {
|
|
1335
|
+
const isStreamed = Boolean(params.streamed);
|
|
1336
|
+
const eventPrefix = isStreamed ? "stream" : "generate";
|
|
1337
|
+
this.logger?.debug(`IgniterAgent.${eventPrefix} started`, {
|
|
1338
|
+
"ctx.agent.name": this.getName(),
|
|
1339
|
+
"ctx.agent.chatId": params.chatId,
|
|
1340
|
+
"ctx.agent.userId": params.userId,
|
|
1341
|
+
"ctx.generation.inputMessages": options.messages?.length || 0,
|
|
1342
|
+
"ctx.generation.streamed": isStreamed
|
|
1172
1343
|
});
|
|
1344
|
+
this.telemetry?.emit(`igniter.agent.generation.${eventPrefix}.started`, {
|
|
1345
|
+
level: "debug",
|
|
1346
|
+
attributes: {
|
|
1347
|
+
"ctx.agent.name": this.getName(),
|
|
1348
|
+
"ctx.agent.chatId": params.chatId,
|
|
1349
|
+
"ctx.agent.userId": params.userId,
|
|
1350
|
+
"ctx.generation.inputMessages": options.messages?.length || 0,
|
|
1351
|
+
"ctx.generation.streamed": isStreamed
|
|
1352
|
+
}
|
|
1353
|
+
});
|
|
1354
|
+
if (this._agent.instructions && options.options) {
|
|
1355
|
+
if (this._agent.memory?.working?.enabled && this._agent.memory.working.template) {
|
|
1356
|
+
this._agent.instructions = this._agent.instructions.addAppended(
|
|
1357
|
+
"memory",
|
|
1358
|
+
this._agent.memory.working.template
|
|
1359
|
+
);
|
|
1360
|
+
}
|
|
1361
|
+
options.instructions = this._agent.instructions.build(options.options);
|
|
1362
|
+
}
|
|
1363
|
+
if (params.prepareCall) {
|
|
1364
|
+
return params.prepareCall(options);
|
|
1365
|
+
}
|
|
1366
|
+
return options;
|
|
1367
|
+
},
|
|
1368
|
+
onStepFinish: async (step) => {
|
|
1369
|
+
if (params.streamed) {
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
this.logger?.debug("IgniterAgent.generate step", {
|
|
1373
|
+
"ctx.agent.name": this.getName(),
|
|
1374
|
+
"ctx.chatId": params.chatId,
|
|
1375
|
+
"ctx.userId": params.userId,
|
|
1376
|
+
"ctx.generation.usage.inputTokens": step.usage.inputTokens,
|
|
1377
|
+
"ctx.generation.usage.outputTokens": step.usage.outputTokens,
|
|
1378
|
+
"ctx.generation.usage.totalTokens": step.usage.totalTokens,
|
|
1379
|
+
"ctx.generation.streamed": false
|
|
1380
|
+
});
|
|
1381
|
+
this.telemetry?.emit("igniter.agent.generation.generate.step", {
|
|
1382
|
+
level: "debug",
|
|
1383
|
+
attributes: {
|
|
1384
|
+
"ctx.agent.name": this.getName(),
|
|
1385
|
+
"ctx.chatId": params.chatId,
|
|
1386
|
+
"ctx.userId": params.userId,
|
|
1387
|
+
"ctx.generation.usage.inputTokens": step.usage.inputTokens,
|
|
1388
|
+
"ctx.generation.usage.outputTokens": step.usage.outputTokens,
|
|
1389
|
+
"ctx.generation.usage.totalTokens": step.usage.totalTokens,
|
|
1390
|
+
"ctx.generation.streamed": false
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
},
|
|
1394
|
+
onFinish: (result) => {
|
|
1395
|
+
if (params.streamed) {
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
this.logger?.debug("IgniterAgent.generate success", {
|
|
1399
|
+
"ctx.agent.name": this.getName(),
|
|
1400
|
+
"ctx.chatId": params.chatId,
|
|
1401
|
+
"ctx.userId": params.userId,
|
|
1402
|
+
"ctx.generation.usage.inputTokens": result.usage.inputTokens,
|
|
1403
|
+
"ctx.generation.usage.outputTokens": result.usage.outputTokens,
|
|
1404
|
+
"ctx.generation.usage.totalTokens": result.usage.totalTokens,
|
|
1405
|
+
"ctx.generation.streamed": false
|
|
1406
|
+
});
|
|
1407
|
+
this.telemetry?.emit("igniter.agent.generation.generate.success", {
|
|
1408
|
+
level: "debug",
|
|
1409
|
+
attributes: {
|
|
1410
|
+
"ctx.agent.name": this.getName(),
|
|
1411
|
+
"ctx.chatId": params.chatId,
|
|
1412
|
+
"ctx.userId": params.userId,
|
|
1413
|
+
"ctx.generation.usage.inputTokens": result.usage.inputTokens,
|
|
1414
|
+
"ctx.generation.usage.outputTokens": result.usage.outputTokens,
|
|
1415
|
+
"ctx.generation.usage.totalTokens": result.usage.totalTokens,
|
|
1416
|
+
"ctx.generation.streamed": false
|
|
1417
|
+
}
|
|
1418
|
+
});
|
|
1419
|
+
},
|
|
1420
|
+
activeTools: params.activeTools,
|
|
1421
|
+
experimental_context: IgniterAgentContext.create({
|
|
1422
|
+
context: params.context,
|
|
1423
|
+
memory: this._agent.memory,
|
|
1424
|
+
metadata: {
|
|
1425
|
+
agent: this.getName(),
|
|
1426
|
+
chatId: params.chatId,
|
|
1427
|
+
userId: params.userId,
|
|
1428
|
+
requestId: params.requestId,
|
|
1429
|
+
startTime: /* @__PURE__ */ new Date()
|
|
1430
|
+
}
|
|
1431
|
+
}),
|
|
1432
|
+
experimental_download: params.experimental_download,
|
|
1433
|
+
experimental_repairToolCall: params.experimental_repairToolCall,
|
|
1434
|
+
experimental_telemetry: params.experimental_telemetry,
|
|
1435
|
+
frequencyPenalty: params.frequencyPenalty,
|
|
1436
|
+
maxOutputTokens: params.maxOutputTokens,
|
|
1437
|
+
maxRetries: params.maxRetries,
|
|
1438
|
+
output: params.output,
|
|
1439
|
+
prepareStep: params.prepareStep,
|
|
1440
|
+
presencePenalty: params.presencePenalty,
|
|
1441
|
+
providerOptions: params.providerOptions,
|
|
1442
|
+
seed: params.seed,
|
|
1443
|
+
stopSequences: params.stopSequences,
|
|
1444
|
+
stopWhen: params.stopWhen,
|
|
1445
|
+
temperature: params.temperature,
|
|
1446
|
+
toolChoice: params.toolChoice,
|
|
1447
|
+
topK: params.topK,
|
|
1448
|
+
topP: params.topP,
|
|
1449
|
+
headers: params.headers
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
async initializeChatMemory({
|
|
1453
|
+
chatId,
|
|
1454
|
+
userId,
|
|
1455
|
+
agentId,
|
|
1456
|
+
message
|
|
1457
|
+
}) {
|
|
1458
|
+
if (!this.memory || !this._agent.memory?.chats?.enabled) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
let chat = await this.memory.getChat(chatId);
|
|
1462
|
+
const { generateSuggestions, generateTitle } = this._agent.memory.chats;
|
|
1463
|
+
if (!chat) {
|
|
1464
|
+
let title = "New conversation";
|
|
1465
|
+
if (generateTitle?.enabled) {
|
|
1466
|
+
const response = await ai.generateText({
|
|
1467
|
+
model: generateTitle.model || this._agent.model,
|
|
1468
|
+
messages: [message],
|
|
1469
|
+
system: generateTitle.instructions || "Analyze the chat history and generate a title for the chat",
|
|
1470
|
+
output: ai.Output.object({
|
|
1471
|
+
schema: zod.z.object({
|
|
1472
|
+
title: zod.z.string().min(1).max(100)
|
|
1473
|
+
})
|
|
1474
|
+
})
|
|
1475
|
+
});
|
|
1476
|
+
title = response.output.title;
|
|
1173
1477
|
}
|
|
1478
|
+
await this.memory.saveChat({
|
|
1479
|
+
chatId,
|
|
1480
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1481
|
+
updatedAt: /* @__PURE__ */ new Date(),
|
|
1482
|
+
messageCount: 0,
|
|
1483
|
+
title
|
|
1484
|
+
});
|
|
1485
|
+
chat = await this.memory.getChat(chatId);
|
|
1174
1486
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1487
|
+
if (!chat) {
|
|
1488
|
+
throw new IgniterAgentError({
|
|
1489
|
+
code: "IGNITER_AGENT_MISSING_REQUIRED" /* MISSING_REQUIRED */,
|
|
1490
|
+
message: "Chat not found and could not be created",
|
|
1491
|
+
metadata: {
|
|
1492
|
+
chatId,
|
|
1493
|
+
userId,
|
|
1494
|
+
agentId
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1184
1497
|
}
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1498
|
+
if (!this._agent.memory?.history?.enabled) {
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
const messages = await this.memory.getMessages({
|
|
1502
|
+
chatId,
|
|
1503
|
+
limit: this._agent.memory?.history?.limit
|
|
1190
1504
|
});
|
|
1505
|
+
return messages;
|
|
1506
|
+
}
|
|
1507
|
+
resolveMessageInput(params) {
|
|
1508
|
+
const message = params.message ?? params.messages?.[params.messages.length - 1];
|
|
1509
|
+
if (!message) {
|
|
1510
|
+
throw new IgniterAgentError({
|
|
1511
|
+
code: "IGNITER_AGENT_MISSING_REQUIRED" /* MISSING_REQUIRED */,
|
|
1512
|
+
message: "Either 'message' or 'messages' must be provided",
|
|
1513
|
+
metadata: {
|
|
1514
|
+
missing: "message"
|
|
1515
|
+
}
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
const messages = params.message ? [message] : params.messages || [];
|
|
1519
|
+
return { message, messages };
|
|
1520
|
+
}
|
|
1521
|
+
initializeTools({
|
|
1522
|
+
chatId,
|
|
1523
|
+
userId,
|
|
1524
|
+
agentId
|
|
1525
|
+
}) {
|
|
1526
|
+
const toolsets = this.getToolsets();
|
|
1527
|
+
const allTools = {};
|
|
1528
|
+
for (const toolset of Object.values(toolsets)) {
|
|
1529
|
+
for (const [toolName, tool3] of Object.entries(toolset.tools)) {
|
|
1530
|
+
allTools[toolName] = {
|
|
1531
|
+
...tool3,
|
|
1532
|
+
execute: async (args, options) => {
|
|
1533
|
+
if (!tool3.execute) {
|
|
1534
|
+
throw new IgniterAgentError({
|
|
1535
|
+
code: "IGNITER_AGENT_MISSING_REQUIRED" /* MISSING_REQUIRED */,
|
|
1536
|
+
message: "Tool does not have an execute function",
|
|
1537
|
+
metadata: { toolName }
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
try {
|
|
1541
|
+
const startTime = Date.now();
|
|
1542
|
+
const toolsetName = toolset.name ?? "unknown";
|
|
1543
|
+
const toolAttributes = {
|
|
1544
|
+
"ctx.agent.name": this.getName(),
|
|
1545
|
+
"ctx.tool.toolset": toolsetName,
|
|
1546
|
+
"ctx.tool.name": toolName,
|
|
1547
|
+
"ctx.tool.fullName": `${toolsetName}.${toolName}`
|
|
1548
|
+
};
|
|
1549
|
+
this.hooks.onToolCallStart?.(this.getName(), toolName, args);
|
|
1550
|
+
this.telemetry?.emit("igniter.agent.tool.execute.started", {
|
|
1551
|
+
level: "debug",
|
|
1552
|
+
attributes: toolAttributes
|
|
1553
|
+
});
|
|
1554
|
+
const result = await tool3.execute(args, {
|
|
1555
|
+
...options,
|
|
1556
|
+
experimental_context: {
|
|
1557
|
+
...options.experimental_context || {},
|
|
1558
|
+
chatId,
|
|
1559
|
+
userId,
|
|
1560
|
+
agentId
|
|
1561
|
+
}
|
|
1562
|
+
});
|
|
1563
|
+
this.telemetry?.emit("igniter.agent.tool.execute.success", {
|
|
1564
|
+
level: "debug",
|
|
1565
|
+
attributes: {
|
|
1566
|
+
...toolAttributes,
|
|
1567
|
+
"ctx.tool.durationMs": Date.now() - startTime
|
|
1568
|
+
}
|
|
1569
|
+
});
|
|
1570
|
+
this.hooks.onToolCallEnd?.(this.getName(), toolName, result);
|
|
1571
|
+
return {
|
|
1572
|
+
success: true,
|
|
1573
|
+
result
|
|
1574
|
+
};
|
|
1575
|
+
} catch (error) {
|
|
1576
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
1577
|
+
const toolsetName = toolset.name ?? "unknown";
|
|
1578
|
+
this.telemetry?.emit("igniter.agent.tool.execute.error", {
|
|
1579
|
+
level: "error",
|
|
1580
|
+
attributes: {
|
|
1581
|
+
"ctx.agent.name": this.getName(),
|
|
1582
|
+
"ctx.tool.toolset": toolsetName,
|
|
1583
|
+
"ctx.tool.name": toolName,
|
|
1584
|
+
"ctx.tool.fullName": `${toolsetName}.${toolName}`,
|
|
1585
|
+
...this.getErrorAttributes(err, "tool.execute")
|
|
1586
|
+
}
|
|
1587
|
+
});
|
|
1588
|
+
this.hooks.onToolCallError?.(this.getName(), toolName, err);
|
|
1589
|
+
throw err;
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
if (this._agent.memory?.working?.enabled) {
|
|
1596
|
+
const scope = this._agent.memory?.working.scope;
|
|
1597
|
+
const isChatMemory = scope === "chat";
|
|
1598
|
+
const identifier = isChatMemory ? chatId : userId;
|
|
1599
|
+
allTools["internal__update_working_memory"] = ai.tool({
|
|
1600
|
+
description: "Remember important information for later in the conversation",
|
|
1601
|
+
inputSchema: zod.z.object({
|
|
1602
|
+
content: zod.z.string().describe("Updated working memory following the template structure")
|
|
1603
|
+
}),
|
|
1604
|
+
execute: async (args, options) => {
|
|
1605
|
+
const { content } = args;
|
|
1606
|
+
if (this.memory) {
|
|
1607
|
+
await this.memory.updateWorkingMemory({
|
|
1608
|
+
scope,
|
|
1609
|
+
identifier,
|
|
1610
|
+
content
|
|
1611
|
+
});
|
|
1612
|
+
} else {
|
|
1613
|
+
await this._agent.memory?.provider.updateWorkingMemory({
|
|
1614
|
+
scope,
|
|
1615
|
+
identifier,
|
|
1616
|
+
content
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1619
|
+
return {
|
|
1620
|
+
success: true
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1623
|
+
});
|
|
1624
|
+
if (this._agent.memory?.history?.enabled) {
|
|
1625
|
+
allTools["internal__search_on_chat_history"] = ai.tool({
|
|
1626
|
+
description: "Search on chat history",
|
|
1627
|
+
inputSchema: zod.z.object({
|
|
1628
|
+
content: zod.z.string().describe("Search query"),
|
|
1629
|
+
limit: zod.z.number().optional().describe("Limit number of results"),
|
|
1630
|
+
dateFrom: zod.z.date().optional().describe("Search from date"),
|
|
1631
|
+
dateTo: zod.z.date().optional().describe("Search to date")
|
|
1632
|
+
}),
|
|
1633
|
+
execute: async (args, options) => {
|
|
1634
|
+
const { content, limit, dateFrom, dateTo } = args;
|
|
1635
|
+
const result = await this._agent.memory?.provider?.search?.({
|
|
1636
|
+
chatId,
|
|
1637
|
+
userId,
|
|
1638
|
+
limit,
|
|
1639
|
+
search: content,
|
|
1640
|
+
dateFrom,
|
|
1641
|
+
dateTo
|
|
1642
|
+
});
|
|
1643
|
+
return {
|
|
1644
|
+
success: true,
|
|
1645
|
+
result
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
});
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return allTools;
|
|
1191
1652
|
}
|
|
1192
1653
|
async initializeMCPClient(mcpConfig) {
|
|
1193
1654
|
if (this._agent.toolsets[mcpConfig.name]) {
|
|
@@ -1367,8 +1828,9 @@ var resolvePath = (value, path) => {
|
|
|
1367
1828
|
}, value);
|
|
1368
1829
|
};
|
|
1369
1830
|
var IgniterAgentPromptBuilder = class _IgniterAgentPromptBuilder {
|
|
1370
|
-
constructor(template) {
|
|
1831
|
+
constructor(template, appended) {
|
|
1371
1832
|
this.template = template;
|
|
1833
|
+
this.appended = appended;
|
|
1372
1834
|
}
|
|
1373
1835
|
/**
|
|
1374
1836
|
* Creates a new prompt builder.
|
|
@@ -1376,9 +1838,10 @@ var IgniterAgentPromptBuilder = class _IgniterAgentPromptBuilder {
|
|
|
1376
1838
|
* @param template - Prompt template string with {{placeholders}}
|
|
1377
1839
|
* @returns A new prompt builder instance
|
|
1378
1840
|
*/
|
|
1379
|
-
static create(template) {
|
|
1841
|
+
static create(template, appended = {}) {
|
|
1380
1842
|
return new _IgniterAgentPromptBuilder(
|
|
1381
|
-
template
|
|
1843
|
+
template,
|
|
1844
|
+
appended
|
|
1382
1845
|
);
|
|
1383
1846
|
}
|
|
1384
1847
|
/**
|
|
@@ -1388,10 +1851,53 @@ var IgniterAgentPromptBuilder = class _IgniterAgentPromptBuilder {
|
|
|
1388
1851
|
* @returns The resolved prompt string
|
|
1389
1852
|
*/
|
|
1390
1853
|
build(context) {
|
|
1391
|
-
|
|
1854
|
+
const resolveTemplate = (template) => template.replace(TEMPLATE_PATTERN, (_match, path) => {
|
|
1392
1855
|
const value = resolvePath(context, String(path));
|
|
1393
1856
|
return value === void 0 || value === null ? "" : String(value);
|
|
1394
1857
|
});
|
|
1858
|
+
const appendedTemplates = Object.values(this.appended).map((prompt) => {
|
|
1859
|
+
if (typeof prompt === "string") {
|
|
1860
|
+
return resolveTemplate(prompt);
|
|
1861
|
+
}
|
|
1862
|
+
if (prompt && typeof prompt === "object" && "build" in prompt) {
|
|
1863
|
+
return prompt.build(context);
|
|
1864
|
+
}
|
|
1865
|
+
return "";
|
|
1866
|
+
});
|
|
1867
|
+
const appendedString = appendedTemplates.filter(Boolean).join("\n\n");
|
|
1868
|
+
const templateString = resolveTemplate(this.template);
|
|
1869
|
+
if (!appendedString) {
|
|
1870
|
+
return templateString;
|
|
1871
|
+
}
|
|
1872
|
+
return templateString + "\n\n" + appendedString;
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Appends another prompt template to this one.
|
|
1876
|
+
*/
|
|
1877
|
+
addAppended(key, prompt) {
|
|
1878
|
+
return new _IgniterAgentPromptBuilder(
|
|
1879
|
+
this.template,
|
|
1880
|
+
{
|
|
1881
|
+
...this.appended,
|
|
1882
|
+
[key]: prompt
|
|
1883
|
+
}
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
/**
|
|
1887
|
+
* Removes an appended prompt template from this one.
|
|
1888
|
+
*/
|
|
1889
|
+
removeAppended(key) {
|
|
1890
|
+
const { [key]: _, ...rest } = this.appended;
|
|
1891
|
+
return new _IgniterAgentPromptBuilder(
|
|
1892
|
+
this.template,
|
|
1893
|
+
rest
|
|
1894
|
+
);
|
|
1895
|
+
}
|
|
1896
|
+
/**
|
|
1897
|
+
* Returns the appended prompts.
|
|
1898
|
+
*/
|
|
1899
|
+
getAppended() {
|
|
1900
|
+
return this.appended;
|
|
1395
1901
|
}
|
|
1396
1902
|
/**
|
|
1397
1903
|
* Returns the raw prompt template string.
|
|
@@ -1667,13 +2173,13 @@ var IgniterAgentBuilder = class _IgniterAgentBuilder {
|
|
|
1667
2173
|
*
|
|
1668
2174
|
* // Context is type-safe when calling generate
|
|
1669
2175
|
* await agent.generate({
|
|
1670
|
-
*
|
|
1671
|
-
*
|
|
1672
|
-
*
|
|
1673
|
-
* chatId: 'chat_456',
|
|
2176
|
+
* chatId: 'chat_456',
|
|
2177
|
+
* userId: 'user_123',
|
|
2178
|
+
* context: {
|
|
1674
2179
|
* userRole: 'admin',
|
|
1675
2180
|
* preferences: { language: 'pt' }
|
|
1676
|
-
* }
|
|
2181
|
+
* },
|
|
2182
|
+
* message: { role: 'user', content: 'Hello!' }
|
|
1677
2183
|
* });
|
|
1678
2184
|
* ```
|
|
1679
2185
|
*
|
|
@@ -1803,7 +2309,10 @@ var IgniterAgentBuilder = class _IgniterAgentBuilder {
|
|
|
1803
2309
|
*
|
|
1804
2310
|
* // Generate a response
|
|
1805
2311
|
* const result = await agent.generate({
|
|
1806
|
-
*
|
|
2312
|
+
* chatId: 'chat_123',
|
|
2313
|
+
* userId: 'user_123',
|
|
2314
|
+
* context: {},
|
|
2315
|
+
* message: { role: 'user', content: 'Hello!' }
|
|
1807
2316
|
* });
|
|
1808
2317
|
*
|
|
1809
2318
|
* // Access configuration
|
|
@@ -3736,144 +4245,12 @@ var IgniterAgentJSONFileAdapter = class _IgniterAgentJSONFileAdapter {
|
|
|
3736
4245
|
}
|
|
3737
4246
|
};
|
|
3738
4247
|
|
|
3739
|
-
// src/utils/strings.ts
|
|
3740
|
-
var IgniterAgentStringUtils = class {
|
|
3741
|
-
/**
|
|
3742
|
-
* Generates a unique identifier.
|
|
3743
|
-
*/
|
|
3744
|
-
static generateId(prefix) {
|
|
3745
|
-
const random = Math.random().toString(36).substring(2, 12);
|
|
3746
|
-
return prefix ? `${prefix}_${random}` : random;
|
|
3747
|
-
}
|
|
3748
|
-
/**
|
|
3749
|
-
* Truncates a string to a maximum length.
|
|
3750
|
-
*/
|
|
3751
|
-
static truncate(str, maxLength, suffix = "...") {
|
|
3752
|
-
if (str.length <= maxLength) return str;
|
|
3753
|
-
return str.slice(0, maxLength - suffix.length) + suffix;
|
|
3754
|
-
}
|
|
3755
|
-
/**
|
|
3756
|
-
* Converts a string to snake_case.
|
|
3757
|
-
*/
|
|
3758
|
-
static toSnakeCase(str) {
|
|
3759
|
-
return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
|
|
3760
|
-
}
|
|
3761
|
-
/**
|
|
3762
|
-
* Converts a string to camelCase.
|
|
3763
|
-
*/
|
|
3764
|
-
static toCamelCase(str) {
|
|
3765
|
-
return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase()).replace(/^(.)/, (char) => char.toLowerCase());
|
|
3766
|
-
}
|
|
3767
|
-
};
|
|
3768
|
-
|
|
3769
|
-
// src/utils/objects.ts
|
|
3770
|
-
var IgniterAgentObjectUtils = class _IgniterAgentObjectUtils {
|
|
3771
|
-
/**
|
|
3772
|
-
* Deep merges two objects.
|
|
3773
|
-
*/
|
|
3774
|
-
static deepMerge(target, source) {
|
|
3775
|
-
const result = { ...target };
|
|
3776
|
-
for (const key in source) {
|
|
3777
|
-
const sourceValue = source[key];
|
|
3778
|
-
const targetValue = target[key];
|
|
3779
|
-
if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
3780
|
-
result[key] = _IgniterAgentObjectUtils.deepMerge(
|
|
3781
|
-
targetValue,
|
|
3782
|
-
sourceValue
|
|
3783
|
-
);
|
|
3784
|
-
} else {
|
|
3785
|
-
result[key] = sourceValue;
|
|
3786
|
-
}
|
|
3787
|
-
}
|
|
3788
|
-
return result;
|
|
3789
|
-
}
|
|
3790
|
-
/**
|
|
3791
|
-
* Picks specified keys from an object.
|
|
3792
|
-
*/
|
|
3793
|
-
static pick(obj, keys) {
|
|
3794
|
-
const result = {};
|
|
3795
|
-
for (const key of keys) {
|
|
3796
|
-
if (key in obj) {
|
|
3797
|
-
result[key] = obj[key];
|
|
3798
|
-
}
|
|
3799
|
-
}
|
|
3800
|
-
return result;
|
|
3801
|
-
}
|
|
3802
|
-
/**
|
|
3803
|
-
* Omits specified keys from an object.
|
|
3804
|
-
*/
|
|
3805
|
-
static omit(obj, keys) {
|
|
3806
|
-
const result = { ...obj };
|
|
3807
|
-
for (const key of keys) {
|
|
3808
|
-
delete result[key];
|
|
3809
|
-
}
|
|
3810
|
-
return result;
|
|
3811
|
-
}
|
|
3812
|
-
};
|
|
3813
|
-
|
|
3814
|
-
// src/utils/async.ts
|
|
3815
|
-
var IgniterAgentAsyncUtils = class _IgniterAgentAsyncUtils {
|
|
3816
|
-
/**
|
|
3817
|
-
* Delays execution for a specified duration.
|
|
3818
|
-
*/
|
|
3819
|
-
static delay(ms) {
|
|
3820
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3821
|
-
}
|
|
3822
|
-
/**
|
|
3823
|
-
* Retries an async function with exponential backoff.
|
|
3824
|
-
*/
|
|
3825
|
-
static async retry(fn, options = {}) {
|
|
3826
|
-
const {
|
|
3827
|
-
maxAttempts = 3,
|
|
3828
|
-
baseDelay = 1e3,
|
|
3829
|
-
maxDelay = 3e4,
|
|
3830
|
-
onRetry
|
|
3831
|
-
} = options;
|
|
3832
|
-
let lastError;
|
|
3833
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
3834
|
-
try {
|
|
3835
|
-
return await fn();
|
|
3836
|
-
} catch (error) {
|
|
3837
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
3838
|
-
if (attempt === maxAttempts) {
|
|
3839
|
-
throw lastError;
|
|
3840
|
-
}
|
|
3841
|
-
onRetry?.(attempt, lastError);
|
|
3842
|
-
const delayMs = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
|
|
3843
|
-
await _IgniterAgentAsyncUtils.delay(delayMs);
|
|
3844
|
-
}
|
|
3845
|
-
}
|
|
3846
|
-
throw lastError;
|
|
3847
|
-
}
|
|
3848
|
-
};
|
|
3849
|
-
|
|
3850
|
-
// src/utils/validation.ts
|
|
3851
|
-
var IgniterAgentValidationUtils = class {
|
|
3852
|
-
/**
|
|
3853
|
-
* Checks if a value is defined (not null or undefined).
|
|
3854
|
-
*/
|
|
3855
|
-
static isDefined(value) {
|
|
3856
|
-
return value !== null && value !== void 0;
|
|
3857
|
-
}
|
|
3858
|
-
/**
|
|
3859
|
-
* Checks if a value is a non-empty string.
|
|
3860
|
-
*/
|
|
3861
|
-
static isNonEmptyString(value) {
|
|
3862
|
-
return typeof value === "string" && value.length > 0;
|
|
3863
|
-
}
|
|
3864
|
-
/**
|
|
3865
|
-
* Checks if a value is a plain object.
|
|
3866
|
-
*/
|
|
3867
|
-
static isPlainObject(value) {
|
|
3868
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
3869
|
-
}
|
|
3870
|
-
};
|
|
3871
|
-
|
|
3872
4248
|
exports.IgniterAgent = IgniterAgent;
|
|
3873
4249
|
exports.IgniterAgentAdapterError = IgniterAgentAdapterError;
|
|
3874
4250
|
exports.IgniterAgentAsyncUtils = IgniterAgentAsyncUtils;
|
|
3875
4251
|
exports.IgniterAgentBuilder = IgniterAgentBuilder;
|
|
3876
4252
|
exports.IgniterAgentConfigError = IgniterAgentConfigError;
|
|
4253
|
+
exports.IgniterAgentContext = IgniterAgentContext;
|
|
3877
4254
|
exports.IgniterAgentCore = IgniterAgentCore;
|
|
3878
4255
|
exports.IgniterAgentError = IgniterAgentError;
|
|
3879
4256
|
exports.IgniterAgentErrorCode = IgniterAgentErrorCode;
|