@agentmark-ai/shared-utils 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +40 -1
- package/dist/index.d.ts +40 -1
- package/dist/index.js +56 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +54 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -558,4 +558,43 @@ declare function normalizeSpan(resource: OtelResource, scope: OtelScope, span: O
|
|
|
558
558
|
*/
|
|
559
559
|
declare function normalizeOtlpSpans(resourceSpans: OtlpResourceSpans[]): NormalizedSpan[];
|
|
560
560
|
|
|
561
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Compute a stable identifier for a dataset row, derived from its input.
|
|
563
|
+
*
|
|
564
|
+
* The identifier survives row reordering, additions, and deletions in the
|
|
565
|
+
* dataset — anything that doesn't change the row's *content* keeps the same
|
|
566
|
+
* id. This is the property regression-vs-baseline comparisons need: the
|
|
567
|
+
* same logical test case in two different runs must produce the same name
|
|
568
|
+
* so the baseline lookup can match them.
|
|
569
|
+
*
|
|
570
|
+
* Format: first 12 hex characters of the MD5 digest of the row's input,
|
|
571
|
+
* canonicalised with sorted keys at every level. This matches the Python
|
|
572
|
+
* runner's implementation byte-for-byte so cross-runtime comparisons
|
|
573
|
+
* (TS-emitted baseline vs. Python-emitted PR run, or vice versa) produce
|
|
574
|
+
* matching identifiers.
|
|
575
|
+
*
|
|
576
|
+
* Falls back to the positional index as a string when the row has no
|
|
577
|
+
* input — in that case there is nothing stable to hash, so positional is
|
|
578
|
+
* the best we can do.
|
|
579
|
+
*
|
|
580
|
+
* Note: we use MD5 here for compatibility with the existing Python
|
|
581
|
+
* implementation. MD5 is not used as a security primitive — it's used as a
|
|
582
|
+
* non-cryptographic content fingerprint, which is its appropriate role.
|
|
583
|
+
*/
|
|
584
|
+
declare function computeDatasetItemName(input: unknown, fallbackIndex: number): string;
|
|
585
|
+
/**
|
|
586
|
+
* Stringify a value as canonical JSON with object keys sorted recursively.
|
|
587
|
+
*
|
|
588
|
+
* Differs from `JSON.stringify`:
|
|
589
|
+
* - Object keys are sorted lexicographically at every level of nesting, so
|
|
590
|
+
* `{a: 1, b: 2}` and `{b: 2, a: 1}` produce the same output.
|
|
591
|
+
* - Non-serializable values (functions, symbols, bigints, undefined) are
|
|
592
|
+
* coerced to strings via `String(value)`, matching Python's `default=str`
|
|
593
|
+
* behavior in `json.dumps`.
|
|
594
|
+
*
|
|
595
|
+
* Exported for testing and for callers that need the same canonicalisation
|
|
596
|
+
* for purposes other than item-name hashing.
|
|
597
|
+
*/
|
|
598
|
+
declare function canonicalJsonStringify(value: unknown): string;
|
|
599
|
+
|
|
600
|
+
export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, canonicalJsonStringify, computeDatasetItemName, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -558,4 +558,43 @@ declare function normalizeSpan(resource: OtelResource, scope: OtelScope, span: O
|
|
|
558
558
|
*/
|
|
559
559
|
declare function normalizeOtlpSpans(resourceSpans: OtlpResourceSpans[]): NormalizedSpan[];
|
|
560
560
|
|
|
561
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Compute a stable identifier for a dataset row, derived from its input.
|
|
563
|
+
*
|
|
564
|
+
* The identifier survives row reordering, additions, and deletions in the
|
|
565
|
+
* dataset — anything that doesn't change the row's *content* keeps the same
|
|
566
|
+
* id. This is the property regression-vs-baseline comparisons need: the
|
|
567
|
+
* same logical test case in two different runs must produce the same name
|
|
568
|
+
* so the baseline lookup can match them.
|
|
569
|
+
*
|
|
570
|
+
* Format: first 12 hex characters of the MD5 digest of the row's input,
|
|
571
|
+
* canonicalised with sorted keys at every level. This matches the Python
|
|
572
|
+
* runner's implementation byte-for-byte so cross-runtime comparisons
|
|
573
|
+
* (TS-emitted baseline vs. Python-emitted PR run, or vice versa) produce
|
|
574
|
+
* matching identifiers.
|
|
575
|
+
*
|
|
576
|
+
* Falls back to the positional index as a string when the row has no
|
|
577
|
+
* input — in that case there is nothing stable to hash, so positional is
|
|
578
|
+
* the best we can do.
|
|
579
|
+
*
|
|
580
|
+
* Note: we use MD5 here for compatibility with the existing Python
|
|
581
|
+
* implementation. MD5 is not used as a security primitive — it's used as a
|
|
582
|
+
* non-cryptographic content fingerprint, which is its appropriate role.
|
|
583
|
+
*/
|
|
584
|
+
declare function computeDatasetItemName(input: unknown, fallbackIndex: number): string;
|
|
585
|
+
/**
|
|
586
|
+
* Stringify a value as canonical JSON with object keys sorted recursively.
|
|
587
|
+
*
|
|
588
|
+
* Differs from `JSON.stringify`:
|
|
589
|
+
* - Object keys are sorted lexicographically at every level of nesting, so
|
|
590
|
+
* `{a: 1, b: 2}` and `{b: 2, a: 1}` produce the same output.
|
|
591
|
+
* - Non-serializable values (functions, symbols, bigints, undefined) are
|
|
592
|
+
* coerced to strings via `String(value)`, matching Python's `default=str`
|
|
593
|
+
* behavior in `json.dumps`.
|
|
594
|
+
*
|
|
595
|
+
* Exported for testing and for callers that need the same canonicalisation
|
|
596
|
+
* for purposes other than item-name hashing.
|
|
597
|
+
*/
|
|
598
|
+
declare function canonicalJsonStringify(value: unknown): string;
|
|
599
|
+
|
|
600
|
+
export { AGENTMARK_SCOPE_NAME, AgentMarkTransformer, type AgentmarkConfig, type AgentmarkModelConfig, type AgentmarkModelSchema, type AgentmarkModelSettingsConfig, type AgentmarkModelSettingsSchema, AiSdkTransformer, type AiSdkVersion, type AttributeExtractor, AgentMarkTransformer as ClaudeAgentTransformer, type GenerateTypesLanguage, MastraTransformer, type McpServerConfig, type McpServers, type McpStdioServerConfig, type McpUrlServerConfig, type Message, type ModelSettingsTypeAspectRatio, type ModelSettingsTypeImageSize, type ModelSettingsTypeSelect, type ModelSettingsTypeSlider, type NormalizedSpan, type OtelEvent, OtelGenAiTransformer, type OtelLink, type OtelResource, type OtelScope, type OtelSpan, type OtlpAttribute, type OtlpAttributeValue, type OtlpEvent, type OtlpLink, type OtlpResource, type OtlpResourceSpans, type OtlpScope, type OtlpScopeSpans, type OtlpSpan, SEMANTIC_KINDS, type ScopeTransformer, type SemanticKind, SpanType, type StandardMessageContent, type StandardTextContent, type StandardToolCallContent, type StandardToolResultContent, type ToolCall, TransformerRegistry, TypeClassifier, canonicalJsonStringify, computeDatasetItemName, convertOtlpAttributes, createSignature, detectVersion, extractCustomMetadata, extractReasoningFromProviderMetadata, extractResourceScopeSpan, fetchPromptsFrontmatter, findPromptFiles, generateTypeDefinitions, generateUnique8CharString, normalizeOtlpSpans, normalizeSpan, parseAgentMarkAttributes, parseMetadata, parseTokens, registry, resolveSemanticKind, toFrontMatter, typeClassifier, verifySignature };
|
package/dist/index.js
CHANGED
|
@@ -40,6 +40,8 @@ __export(index_exports, {
|
|
|
40
40
|
SpanType: () => SpanType,
|
|
41
41
|
TransformerRegistry: () => TransformerRegistry,
|
|
42
42
|
TypeClassifier: () => TypeClassifier,
|
|
43
|
+
canonicalJsonStringify: () => canonicalJsonStringify,
|
|
44
|
+
computeDatasetItemName: () => computeDatasetItemName,
|
|
43
45
|
convertOtlpAttributes: () => convertOtlpAttributes,
|
|
44
46
|
createSignature: () => createSignature,
|
|
45
47
|
detectVersion: () => detectVersion,
|
|
@@ -228,27 +230,26 @@ async function generateTypeDefinitionsV1_0(prompts) {
|
|
|
228
230
|
for (const prompt of prompts) {
|
|
229
231
|
const { path: promptPath, input_schema } = prompt;
|
|
230
232
|
const name = getInterfaceName(promptPath);
|
|
231
|
-
let tools = {};
|
|
232
233
|
try {
|
|
233
234
|
let kind = "text";
|
|
234
235
|
let output_schema = null;
|
|
236
|
+
let hasTools = false;
|
|
235
237
|
if ("text_config" in prompt) {
|
|
236
238
|
kind = "text";
|
|
237
|
-
|
|
239
|
+
hasTools = Array.isArray(prompt.text_config.tools) ? prompt.text_config.tools.length > 0 : !!prompt.text_config.tools;
|
|
238
240
|
} else if ("object_config" in prompt) {
|
|
239
241
|
kind = "object";
|
|
240
|
-
|
|
242
|
+
hasTools = Array.isArray(prompt.object_config.tools) ? prompt.object_config.tools.length > 0 : !!prompt.object_config.tools;
|
|
241
243
|
output_schema = prompt.object_config.schema;
|
|
242
244
|
} else if ("image_config" in prompt) {
|
|
243
245
|
kind = "image";
|
|
244
|
-
|
|
246
|
+
hasTools = Array.isArray(prompt.image_config.tools) ? prompt.image_config.tools.length > 0 : !!prompt.image_config.tools;
|
|
245
247
|
}
|
|
246
248
|
const compile = await getCompile();
|
|
247
249
|
const inputInterface = input_schema ? await compile(input_schema, `${name}In`, {
|
|
248
250
|
bannerComment: "",
|
|
249
251
|
additionalProperties: false
|
|
250
252
|
}) : `interface ${name}In { [key: string]: any }`;
|
|
251
|
-
const toolTypes = await generateToolTypes(tools);
|
|
252
253
|
const outputInterface = output_schema ? await compile(output_schema, `${name}Out`, {
|
|
253
254
|
bannerComment: "",
|
|
254
255
|
additionalProperties: false
|
|
@@ -257,12 +258,11 @@ async function generateTypeDefinitionsV1_0(prompts) {
|
|
|
257
258
|
inputInterface.replace("export interface", "interface"),
|
|
258
259
|
outputInterface.replace("export type", "type").replace("export interface", "interface")
|
|
259
260
|
);
|
|
260
|
-
output += toolTypes || "";
|
|
261
261
|
output += `type ${name} = {
|
|
262
262
|
kind: '${kind}';
|
|
263
263
|
input: ${name}In;
|
|
264
|
-
output: ${name}Out;${
|
|
265
|
-
tools?:
|
|
264
|
+
output: ${name}Out;${hasTools ? `
|
|
265
|
+
tools?: string[];` : ""}
|
|
266
266
|
};
|
|
267
267
|
|
|
268
268
|
`;
|
|
@@ -689,6 +689,7 @@ async function generateTypeDefinitions(prompts, language = "typescript") {
|
|
|
689
689
|
return generateTypeDefinitionsV0(prompts);
|
|
690
690
|
}
|
|
691
691
|
async function fetchPromptsFrontmatter(options) {
|
|
692
|
+
var _a, _b, _c;
|
|
692
693
|
if (options.local) {
|
|
693
694
|
const baseUrl = `http://localhost:${options.local}`;
|
|
694
695
|
try {
|
|
@@ -698,7 +699,8 @@ async function fetchPromptsFrontmatter(options) {
|
|
|
698
699
|
`Failed to fetch prompt paths: ${pathsResponse.statusText}`
|
|
699
700
|
);
|
|
700
701
|
}
|
|
701
|
-
const
|
|
702
|
+
const body = await pathsResponse.json();
|
|
703
|
+
const paths = (_c = (_b = (_a = body == null ? void 0 : body.data) == null ? void 0 : _a.paths) != null ? _b : body == null ? void 0 : body.paths) != null ? _c : [];
|
|
702
704
|
return Promise.all(
|
|
703
705
|
paths.map(async (promptPath) => {
|
|
704
706
|
const templateResponse = await fetch(
|
|
@@ -764,34 +766,6 @@ async function fetchPromptsFrontmatter(options) {
|
|
|
764
766
|
}
|
|
765
767
|
throw new Error("Either --local or --root-dir must be specified");
|
|
766
768
|
}
|
|
767
|
-
async function generateToolTypes(tools) {
|
|
768
|
-
const toolArgTypes = [];
|
|
769
|
-
for (const [toolName, schema] of Object.entries(tools)) {
|
|
770
|
-
const typeName = `${getToolInterfaceName(toolName)}Args`;
|
|
771
|
-
try {
|
|
772
|
-
const compile = await getCompile();
|
|
773
|
-
const argInterface = schema.parameters ? await compile(schema.parameters, typeName, {
|
|
774
|
-
bannerComment: "",
|
|
775
|
-
additionalProperties: false
|
|
776
|
-
}) : `type ${typeName} = { ${Object.entries(schema.parameters || {}).map(([key]) => `${key}: any`).join("; ")} };`;
|
|
777
|
-
toolArgTypes.push(
|
|
778
|
-
argInterface.replace("export type", "type").replace("export interface", "interface")
|
|
779
|
-
);
|
|
780
|
-
} catch (error) {
|
|
781
|
-
console.error(`Error processing tool ${toolName}:`, error);
|
|
782
|
-
toolArgTypes.push(`type ${typeName} = { [key: string]: any };`);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
if (Object.keys(tools).length > 0) {
|
|
786
|
-
const toolsInterface = `export interface Tools {
|
|
787
|
-
${Object.keys(tools).map(
|
|
788
|
-
(toolName) => ` ${toolName}: { args: ${getToolInterfaceName(toolName)}Args };`
|
|
789
|
-
).join("\n")}
|
|
790
|
-
}`;
|
|
791
|
-
return toolArgTypes.join("\n\n") + "\n\n" + toolsInterface + "\n\n";
|
|
792
|
-
}
|
|
793
|
-
return null;
|
|
794
|
-
}
|
|
795
769
|
|
|
796
770
|
// src/normalizer/types.ts
|
|
797
771
|
var SpanType = /* @__PURE__ */ ((SpanType2) => {
|
|
@@ -1778,6 +1752,7 @@ var AgentMarkTransformer = class {
|
|
|
1778
1752
|
* Transform the span and extract normalized fields from GenAI attributes.
|
|
1779
1753
|
*/
|
|
1780
1754
|
transform(_span, attributes) {
|
|
1755
|
+
var _a;
|
|
1781
1756
|
const result = {};
|
|
1782
1757
|
const responseModel = attributes[GenAIAttributes.RESPONSE_MODEL];
|
|
1783
1758
|
const requestModel = attributes[GenAIAttributes.REQUEST_MODEL];
|
|
@@ -1851,7 +1826,7 @@ var AgentMarkTransformer = class {
|
|
|
1851
1826
|
} catch {
|
|
1852
1827
|
}
|
|
1853
1828
|
}
|
|
1854
|
-
const amInput = attributes["agentmark.input"];
|
|
1829
|
+
const amInput = (_a = attributes["agentmark.input"]) != null ? _a : attributes["agentmark.props"];
|
|
1855
1830
|
if (amInput && typeof amInput === "string" && !result.input) {
|
|
1856
1831
|
result.input = [{ role: "user", content: amInput }];
|
|
1857
1832
|
}
|
|
@@ -1917,9 +1892,16 @@ var Attrs = {
|
|
|
1917
1892
|
RESPONSE_FINISH_REASONS: "gen_ai.response.finish_reasons",
|
|
1918
1893
|
USAGE_INPUT_TOKENS: "gen_ai.usage.input_tokens",
|
|
1919
1894
|
USAGE_OUTPUT_TOKENS: "gen_ai.usage.output_tokens",
|
|
1920
|
-
// v1.37.0+ content attributes
|
|
1895
|
+
// v1.37.0+ content attributes (canonical OTel GenAI semantic conventions).
|
|
1896
|
+
// SDKs that emit the AgentMark-scoped equivalents (`gen_ai.request.input`
|
|
1897
|
+
// / `gen_ai.response.output` — used by `claude-agent-sdk-v0-adapter`) are
|
|
1898
|
+
// also accepted here as fallbacks so an SDK picking either key set
|
|
1899
|
+
// doesn't silently lose IO data on ingest. The canonical pair always wins
|
|
1900
|
+
// when both are present.
|
|
1921
1901
|
INPUT_MESSAGES: "gen_ai.input.messages",
|
|
1922
1902
|
OUTPUT_MESSAGES: "gen_ai.output.messages",
|
|
1903
|
+
REQUEST_INPUT_FALLBACK: "gen_ai.request.input",
|
|
1904
|
+
RESPONSE_OUTPUT_FALLBACK: "gen_ai.response.output",
|
|
1923
1905
|
SYSTEM_INSTRUCTIONS: "gen_ai.system_instructions",
|
|
1924
1906
|
TOOL_DEFINITIONS: "gen_ai.tool.definitions",
|
|
1925
1907
|
// Tool call attributes (v1.37.0+)
|
|
@@ -1984,6 +1966,7 @@ var OtelGenAiTransformer = class {
|
|
|
1984
1966
|
return "SPAN" /* SPAN */;
|
|
1985
1967
|
}
|
|
1986
1968
|
transform(span, attributes) {
|
|
1969
|
+
var _a, _b;
|
|
1987
1970
|
const result = {};
|
|
1988
1971
|
const model = attributes[Attrs.RESPONSE_MODEL] || attributes[Attrs.REQUEST_MODEL];
|
|
1989
1972
|
if (model && typeof model === "string") {
|
|
@@ -2004,12 +1987,12 @@ var OtelGenAiTransformer = class {
|
|
|
2004
1987
|
if (typeof temperature === "number") {
|
|
2005
1988
|
result.settings = { ...result.settings, temperature };
|
|
2006
1989
|
}
|
|
2007
|
-
const inputMessages = attributes[Attrs.INPUT_MESSAGES];
|
|
1990
|
+
const inputMessages = (_a = attributes[Attrs.INPUT_MESSAGES]) != null ? _a : attributes[Attrs.REQUEST_INPUT_FALLBACK];
|
|
2008
1991
|
if (inputMessages && typeof inputMessages === "string") {
|
|
2009
1992
|
const messages = normalizeMessages(inputMessages);
|
|
2010
1993
|
if (messages) result.input = messages;
|
|
2011
1994
|
}
|
|
2012
|
-
const outputMessages = attributes[Attrs.OUTPUT_MESSAGES];
|
|
1995
|
+
const outputMessages = (_b = attributes[Attrs.OUTPUT_MESSAGES]) != null ? _b : attributes[Attrs.RESPONSE_OUTPUT_FALLBACK];
|
|
2013
1996
|
if (outputMessages && typeof outputMessages === "string") {
|
|
2014
1997
|
const extracted = extractStructuredOutput(outputMessages);
|
|
2015
1998
|
if (extracted) {
|
|
@@ -2339,6 +2322,36 @@ function normalizeOtlpSpans(resourceSpans) {
|
|
|
2339
2322
|
}
|
|
2340
2323
|
return normalizedSpans;
|
|
2341
2324
|
}
|
|
2325
|
+
|
|
2326
|
+
// src/dataset-item-name.ts
|
|
2327
|
+
var import_node_crypto = require("crypto");
|
|
2328
|
+
function computeDatasetItemName(input, fallbackIndex) {
|
|
2329
|
+
if (input === void 0 || input === null) {
|
|
2330
|
+
return String(fallbackIndex);
|
|
2331
|
+
}
|
|
2332
|
+
const canonical = canonicalJsonStringify(input);
|
|
2333
|
+
return (0, import_node_crypto.createHash)("md5").update(canonical).digest("hex").slice(0, 12);
|
|
2334
|
+
}
|
|
2335
|
+
function canonicalJsonStringify(value) {
|
|
2336
|
+
if (value === null) return "null";
|
|
2337
|
+
if (value === void 0) return JSON.stringify(String(void 0));
|
|
2338
|
+
const t = typeof value;
|
|
2339
|
+
if (t === "string" || t === "number" || t === "boolean") {
|
|
2340
|
+
return JSON.stringify(value);
|
|
2341
|
+
}
|
|
2342
|
+
if (t === "bigint" || t === "function" || t === "symbol") {
|
|
2343
|
+
return JSON.stringify(String(value));
|
|
2344
|
+
}
|
|
2345
|
+
if (Array.isArray(value)) {
|
|
2346
|
+
return "[" + value.map(canonicalJsonStringify).join(",") + "]";
|
|
2347
|
+
}
|
|
2348
|
+
const obj = value;
|
|
2349
|
+
const keys = Object.keys(obj).sort();
|
|
2350
|
+
const parts = keys.map((k) => {
|
|
2351
|
+
return JSON.stringify(k) + ":" + canonicalJsonStringify(obj[k]);
|
|
2352
|
+
});
|
|
2353
|
+
return "{" + parts.join(",") + "}";
|
|
2354
|
+
}
|
|
2342
2355
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2343
2356
|
0 && (module.exports = {
|
|
2344
2357
|
AGENTMARK_SCOPE_NAME,
|
|
@@ -2351,6 +2364,8 @@ function normalizeOtlpSpans(resourceSpans) {
|
|
|
2351
2364
|
SpanType,
|
|
2352
2365
|
TransformerRegistry,
|
|
2353
2366
|
TypeClassifier,
|
|
2367
|
+
canonicalJsonStringify,
|
|
2368
|
+
computeDatasetItemName,
|
|
2354
2369
|
convertOtlpAttributes,
|
|
2355
2370
|
createSignature,
|
|
2356
2371
|
detectVersion,
|