@prefactor/core 0.3.1 → 0.3.3

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/dist/index.js CHANGED
@@ -561,6 +561,32 @@ function calculateRetryDelay(attempt, config, random = Math.random) {
561
561
  return Math.round(baseDelay * jitterMultiplier);
562
562
  }
563
563
 
564
+ // packages/core/src/version.ts
565
+ var PACKAGE_NAME = "@prefactor/core";
566
+ var PACKAGE_VERSION = "0.3.3";
567
+
568
+ // packages/core/src/transport/http/sdk-request-header.ts
569
+ var DEFAULT_SDK_REQUEST_HEADER = formatSdkHeaderEntry(PACKAGE_NAME, PACKAGE_VERSION);
570
+ function buildSdkRequestHeader(...entries) {
571
+ const parts = [
572
+ ...entries.filter((entry) => Boolean(entry)).map((entry) => normalizeSdkHeaderEntry(entry)),
573
+ DEFAULT_SDK_REQUEST_HEADER
574
+ ];
575
+ return Array.from(new Set(parts)).join(" ");
576
+ }
577
+ function normalizeSdkHeaderEntry(entry) {
578
+ const atIndex = entry.lastIndexOf("@");
579
+ if (atIndex <= 0) {
580
+ return entry;
581
+ }
582
+ const packageName = entry.slice(0, atIndex);
583
+ const version = entry.slice(atIndex + 1);
584
+ return version ? `${packageName}@${version}` : packageName;
585
+ }
586
+ function formatSdkHeaderEntry(packageName, version) {
587
+ return `${packageName}@${version}`;
588
+ }
589
+
564
590
  // packages/core/src/transport/http/http-client.ts
565
591
  class HttpClientError extends Error {
566
592
  url;
@@ -586,11 +612,13 @@ class HttpClient {
586
612
  fetchFn;
587
613
  sleep;
588
614
  random;
589
- constructor(config, dependencies = {}) {
615
+ sdkHeader;
616
+ constructor(config, dependencies = {}, sdkHeaderEntry) {
590
617
  this.config = config;
591
618
  this.fetchFn = dependencies.fetchFn ?? fetch;
592
619
  this.sleep = dependencies.sleep ?? ((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));
593
620
  this.random = dependencies.random ?? Math.random;
621
+ this.sdkHeader = sdkHeaderEntry ? buildSdkRequestHeader(sdkHeaderEntry) : DEFAULT_SDK_REQUEST_HEADER;
594
622
  }
595
623
  async request(path, options = {}) {
596
624
  const url = new URL(path, this.config.apiUrl).toString();
@@ -599,6 +627,7 @@ class HttpClient {
599
627
  while (true) {
600
628
  const headers = new Headers(options.headers);
601
629
  headers.set("Authorization", `Bearer ${this.config.apiToken}`);
630
+ headers.set("X-Prefactor-SDK", this.sdkHeader);
602
631
  if (options.body !== undefined && !headers.has("Content-Type")) {
603
632
  headers.set("Content-Type", "application/json");
604
633
  }
@@ -738,9 +767,9 @@ class HttpTransport {
738
767
  spanIdMap = new Map;
739
768
  pendingFinishes = new Map;
740
769
  pendingChildren = new Map;
741
- constructor(config) {
770
+ constructor(config, sdkHeaderEntry) {
742
771
  this.config = config;
743
- const httpClient = new HttpClient(config);
772
+ const httpClient = sdkHeaderEntry === undefined ? new HttpClient(config) : new HttpClient(config, {}, sdkHeaderEntry);
744
773
  this.agentInstanceClient = new AgentInstanceClient(httpClient);
745
774
  this.agentSpanClient = new AgentSpanClient(httpClient);
746
775
  this.taskExecutor = new TaskExecutor(this.actionQueue, this.processAction, {
@@ -1026,12 +1055,12 @@ class HttpTransport {
1026
1055
  }
1027
1056
 
1028
1057
  // packages/core/src/create-core.ts
1029
- function createCore(config) {
1058
+ function createCore(config, options = {}) {
1030
1059
  if (!config.httpConfig) {
1031
1060
  throw new Error("HTTP transport requires httpConfig to be provided in configuration");
1032
1061
  }
1033
1062
  const httpConfig = HttpTransportConfigSchema.parse(config.httpConfig);
1034
- const transport = new HttpTransport(httpConfig);
1063
+ const transport = options.sdkHeaderEntry === undefined ? new HttpTransport(httpConfig) : new HttpTransport(httpConfig, options.sdkHeaderEntry);
1035
1064
  let partition;
1036
1065
  if (config.httpConfig.agentId) {
1037
1066
  try {
@@ -1143,7 +1172,8 @@ class PrefactorClient {
1143
1172
  }
1144
1173
  }
1145
1174
  function init(options) {
1146
- const nextInitKey = buildInitKey(options);
1175
+ const sdkHeaderEntry = options.provider.getSdkHeaderEntry?.();
1176
+ const nextInitKey = buildInitKey(options, sdkHeaderEntry);
1147
1177
  if (prefactorClient) {
1148
1178
  if (prefactorInitKey !== nextInitKey) {
1149
1179
  throw new Error("Prefactor is already initialized with a different provider or configuration. " + "Call shutdown() before re-initializing with different options.");
@@ -1163,7 +1193,21 @@ function init(options) {
1163
1193
  }
1164
1194
  };
1165
1195
  }
1166
- const core = createCore(finalConfig);
1196
+ if (finalConfig.httpConfig?.agentSchema) {
1197
+ const normalizedSchema = options.provider.normalizeAgentSchema?.(finalConfig.httpConfig.agentSchema);
1198
+ if (normalizedSchema) {
1199
+ finalConfig = {
1200
+ ...finalConfig,
1201
+ httpConfig: {
1202
+ ...finalConfig.httpConfig,
1203
+ agentSchema: normalizedSchema
1204
+ }
1205
+ };
1206
+ }
1207
+ }
1208
+ const core = createCore(finalConfig, {
1209
+ sdkHeaderEntry
1210
+ });
1167
1211
  const httpConfig = finalConfig.httpConfig;
1168
1212
  if (httpConfig?.agentSchema) {
1169
1213
  core.agentManager.registerSchema(httpConfig.agentSchema);
@@ -1176,9 +1220,13 @@ function init(options) {
1176
1220
  function getClient() {
1177
1221
  return prefactorClient;
1178
1222
  }
1179
- function buildInitKey(options) {
1223
+ function buildInitKey(options, sdkHeaderEntry) {
1180
1224
  const providerType = options.provider.constructor?.name ?? "anonymous-provider";
1181
- return `${providerType}:${stableStringify2(options.httpConfig ?? null)}`;
1225
+ return stableStringify2({
1226
+ providerType,
1227
+ httpConfig: options.httpConfig ?? null,
1228
+ sdkHeaderEntry: sdkHeaderEntry ?? null
1229
+ });
1182
1230
  }
1183
1231
  function stableStringify2(value) {
1184
1232
  return JSON.stringify(normalizeValue2(value));
@@ -1198,6 +1246,160 @@ function normalizeValue2(value) {
1198
1246
  }
1199
1247
  return value;
1200
1248
  }
1249
+ // packages/core/src/tool-schema.ts
1250
+ var logger2 = getLogger("tool-schema");
1251
+ function normalizeAgentToolSchemas(agentSchema, {
1252
+ defaultAgentSchema,
1253
+ providerName
1254
+ }) {
1255
+ const toolSchemas = extractToolSchemas(agentSchema, providerName);
1256
+ return {
1257
+ agentSchema: mergeWithDefaultAgentSchema(stripToolSchemas(agentSchema), defaultAgentSchema),
1258
+ toolSchemas,
1259
+ toolSpanTypes: buildToolSpanTypes(toolSchemas)
1260
+ };
1261
+ }
1262
+ function resolveMappedSpanType(toolName, toolSpanTypes, defaultSpanType) {
1263
+ return toolSpanTypes?.[toolName] ?? defaultSpanType;
1264
+ }
1265
+ function extractToolSchemas(agentSchema, providerName) {
1266
+ const rawToolSchemas = getRawToolSchemas(agentSchema);
1267
+ if (!rawToolSchemas) {
1268
+ return;
1269
+ }
1270
+ const toolSchemas = {};
1271
+ const toolBySpanType = new Map;
1272
+ for (const [toolName, rawConfig] of Object.entries(rawToolSchemas)) {
1273
+ const parsedToolSchema = parseToolSchemaConfig(toolName, rawConfig, providerName, toolBySpanType);
1274
+ if (!parsedToolSchema) {
1275
+ continue;
1276
+ }
1277
+ toolSchemas[toolName] = parsedToolSchema;
1278
+ }
1279
+ return Object.keys(toolSchemas).length > 0 ? toolSchemas : undefined;
1280
+ }
1281
+ function getRawToolSchemas(agentSchema) {
1282
+ if (!agentSchema || typeof agentSchema !== "object" || Array.isArray(agentSchema)) {
1283
+ return;
1284
+ }
1285
+ const rawToolSchemas = agentSchema.toolSchemas;
1286
+ if (rawToolSchemas === undefined) {
1287
+ return;
1288
+ }
1289
+ if (!rawToolSchemas || typeof rawToolSchemas !== "object" || Array.isArray(rawToolSchemas)) {
1290
+ logger2.warn("Ignoring invalid agentSchema.toolSchemas: expected an object keyed by tool name.");
1291
+ return;
1292
+ }
1293
+ return rawToolSchemas;
1294
+ }
1295
+ function parseToolSchemaConfig(toolName, rawConfig, providerName, toolBySpanType) {
1296
+ if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
1297
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}: expected an object with spanType and inputSchema.`);
1298
+ return;
1299
+ }
1300
+ const config = rawConfig;
1301
+ if (typeof config.spanType !== "string") {
1302
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.spanType: expected a non-empty string.`);
1303
+ return;
1304
+ }
1305
+ const inputSchema = assertValidInputSchema(toolName, config.inputSchema);
1306
+ if (!inputSchema) {
1307
+ return;
1308
+ }
1309
+ const normalizedSpanType = normalizeUniqueToolSpanType(toolName, config.spanType, providerName, toolBySpanType);
1310
+ if (!normalizedSpanType) {
1311
+ return;
1312
+ }
1313
+ return {
1314
+ spanType: normalizedSpanType,
1315
+ inputSchema
1316
+ };
1317
+ }
1318
+ function assertValidInputSchema(toolName, inputSchema) {
1319
+ if (!inputSchema || typeof inputSchema !== "object" || Array.isArray(inputSchema)) {
1320
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.inputSchema: expected an object.`);
1321
+ return;
1322
+ }
1323
+ return inputSchema;
1324
+ }
1325
+ function normalizeUniqueToolSpanType(toolName, spanType, providerName, toolBySpanType) {
1326
+ const normalizedSpanType = normalizeToolSpanType(spanType, toolName, providerName);
1327
+ if (!normalizedSpanType) {
1328
+ return;
1329
+ }
1330
+ const conflictingTool = toolBySpanType.get(normalizedSpanType);
1331
+ if (conflictingTool && conflictingTool !== toolName) {
1332
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.spanType: normalized span type "${normalizedSpanType}" conflicts with "${conflictingTool}".`);
1333
+ return;
1334
+ }
1335
+ toolBySpanType.set(normalizedSpanType, toolName);
1336
+ return normalizedSpanType;
1337
+ }
1338
+ function buildToolSpanTypes(toolSchemas) {
1339
+ if (!toolSchemas) {
1340
+ return;
1341
+ }
1342
+ return Object.fromEntries(Object.entries(toolSchemas).map(([toolName, config]) => [toolName, config.spanType]));
1343
+ }
1344
+ function cloneRecord(value) {
1345
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1346
+ return {};
1347
+ }
1348
+ return { ...value };
1349
+ }
1350
+ function stripToolSchemas(baseSchema) {
1351
+ if (!baseSchema || typeof baseSchema !== "object" || Array.isArray(baseSchema)) {
1352
+ return baseSchema;
1353
+ }
1354
+ const { toolSchemas: _, ...rest } = baseSchema;
1355
+ return rest;
1356
+ }
1357
+ function mergeWithDefaultAgentSchema(baseSchema, defaultAgentSchema) {
1358
+ if (!baseSchema) {
1359
+ return defaultAgentSchema;
1360
+ }
1361
+ return {
1362
+ ...defaultAgentSchema,
1363
+ ...baseSchema,
1364
+ span_schemas: {
1365
+ ...cloneRecord(defaultAgentSchema.span_schemas),
1366
+ ...cloneRecord(baseSchema.span_schemas)
1367
+ },
1368
+ span_result_schemas: {
1369
+ ...cloneRecord(defaultAgentSchema.span_result_schemas),
1370
+ ...cloneRecord(baseSchema.span_result_schemas)
1371
+ }
1372
+ };
1373
+ }
1374
+ function normalizeToolSpanType(spanType, toolName, providerName) {
1375
+ const trimmedSpanType = spanType.trim();
1376
+ if (trimmedSpanType.length === 0) {
1377
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.spanType: expected a non-empty string.`);
1378
+ return;
1379
+ }
1380
+ const providerToolPrefix = `${providerName}:tool:`;
1381
+ if (trimmedSpanType.startsWith(providerToolPrefix)) {
1382
+ const suffix2 = trimmedSpanType.slice(providerToolPrefix.length).replace(/^:+/, "");
1383
+ if (suffix2.length === 0) {
1384
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.spanType: expected a non-empty suffix after normalization.`);
1385
+ return;
1386
+ }
1387
+ return `${providerName}:tool:${suffix2}`;
1388
+ }
1389
+ let suffix = trimmedSpanType;
1390
+ if (suffix.startsWith(`${providerName}:`)) {
1391
+ suffix = suffix.slice(`${providerName}:`.length);
1392
+ }
1393
+ if (suffix.startsWith("tool:")) {
1394
+ suffix = suffix.slice("tool:".length);
1395
+ }
1396
+ suffix = suffix.replace(/^:+/, "");
1397
+ if (suffix.length === 0) {
1398
+ logger2.warn(`Invalid agentSchema.toolSchemas.${toolName}.spanType: expected a non-empty suffix after normalization.`);
1399
+ return;
1400
+ }
1401
+ return `${providerName}:tool:${suffix}`;
1402
+ }
1201
1403
  // packages/core/src/utils/serialization.ts
1202
1404
  function truncateString(value, maxLength) {
1203
1405
  if (value.length <= maxLength) {
@@ -1236,7 +1438,9 @@ export {
1236
1438
  truncateString,
1237
1439
  shutdown,
1238
1440
  serializeValue,
1441
+ resolveMappedSpanType,
1239
1442
  registerShutdownHandler,
1443
+ normalizeAgentToolSchemas,
1240
1444
  init,
1241
1445
  getLogger,
1242
1446
  getClient,
@@ -1260,4 +1464,4 @@ export {
1260
1464
  AgentInstanceClient
1261
1465
  };
1262
1466
 
1263
- //# debugId=4E7D6B116785760064756E2164756E21
1467
+ //# debugId=35742D945196233D64756E2164756E21