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