@glassflow-ai/rius 0.6.1 → 0.7.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.cjs +58 -19
- package/dist/index.d.cts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +59 -20
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -373,7 +373,7 @@ function kindAttributes(kind) {
|
|
|
373
373
|
if (operation !== void 0) attributes[GEN_AI_OPERATION_NAME] = operation;
|
|
374
374
|
return attributes;
|
|
375
375
|
}
|
|
376
|
-
var TRACER_NAME, SERVICE_INSTANCE_ID, OPENINFERENCE_SPAN_KIND, INPUT_VALUE, OUTPUT_VALUE, SESSION_ID, USER_ID, WORKSPACE_ROUTE, GEN_AI_OPERATION_NAME, GEN_AI_PROVIDER_NAME, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_REASONING_LEVEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_CACHE_WRITE_INPUT_TOKENS, GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, GEN_AI_INPUT_MESSAGES, GEN_AI_OUTPUT_MESSAGES, GEN_AI_RESPONSE_FINISH_REASONS, GEN_AI_TOOL_NAME, GEN_AI_TOOL_DEFINITIONS, GEN_AI_REQUEST_PREFIX, MCP_RESULT_TYPE, GEN_AI_FIRST_TOKEN_EVENT, SpanKind, OPERATION_BY_KIND, CONTENT_ATTRIBUTES, LLM_INVOCATION_PARAMETERS, INVOCATION_PARAMETERS_CONTENT_MEMBERS, CONTENT_ATTRIBUTE_PREFIXES, CONTENT_ATTRIBUTE_SUFFIXES, GLASSFLOW_SPAN_PENDING, PENDING_IDENTITY_ATTRIBUTES, PENDING_IDENTITY_PREFIXES;
|
|
376
|
+
var TRACER_NAME, SERVICE_INSTANCE_ID, OPENINFERENCE_SPAN_KIND, INPUT_VALUE, OUTPUT_VALUE, SESSION_ID, USER_ID, WORKSPACE_ROUTE, GEN_AI_OPERATION_NAME, GEN_AI_PROVIDER_NAME, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_REASONING_LEVEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_CACHE_WRITE_INPUT_TOKENS, GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, GEN_AI_INPUT_MESSAGES, GEN_AI_OUTPUT_MESSAGES, GEN_AI_RESPONSE_FINISH_REASONS, GEN_AI_TOOL_NAME, GEN_AI_TOOL_DEFINITIONS, GEN_AI_REQUEST_PREFIX, MCP_METHOD_NAME, MCP_METHOD_TOOLS_CALL, MCP_PROTOCOL_VERSION, ERROR_TYPE, ERROR_TYPE_TOOL_ERROR, MCP_RESULT_TYPE, GEN_AI_FIRST_TOKEN_EVENT, SpanKind, OPERATION_BY_KIND, CONTENT_ATTRIBUTES, LLM_INVOCATION_PARAMETERS, INVOCATION_PARAMETERS_CONTENT_MEMBERS, CONTENT_ATTRIBUTE_PREFIXES, CONTENT_ATTRIBUTE_SUFFIXES, GLASSFLOW_SPAN_PENDING, PENDING_IDENTITY_ATTRIBUTES, PENDING_IDENTITY_PREFIXES;
|
|
377
377
|
var init_semconv = __esm({
|
|
378
378
|
"src/semconv.ts"() {
|
|
379
379
|
"use strict";
|
|
@@ -402,6 +402,11 @@ var init_semconv = __esm({
|
|
|
402
402
|
GEN_AI_TOOL_NAME = "gen_ai.tool.name";
|
|
403
403
|
GEN_AI_TOOL_DEFINITIONS = "gen_ai.tool.definitions";
|
|
404
404
|
GEN_AI_REQUEST_PREFIX = "gen_ai.request.";
|
|
405
|
+
MCP_METHOD_NAME = "mcp.method.name";
|
|
406
|
+
MCP_METHOD_TOOLS_CALL = "tools/call";
|
|
407
|
+
MCP_PROTOCOL_VERSION = "mcp.protocol.version";
|
|
408
|
+
ERROR_TYPE = "error.type";
|
|
409
|
+
ERROR_TYPE_TOOL_ERROR = "tool_error";
|
|
405
410
|
MCP_RESULT_TYPE = "mcp.result_type";
|
|
406
411
|
GEN_AI_FIRST_TOKEN_EVENT = "gen_ai.first_token";
|
|
407
412
|
SpanKind = /* @__PURE__ */ ((SpanKind2) => {
|
|
@@ -503,6 +508,11 @@ var init_semconv = __esm({
|
|
|
503
508
|
GEN_AI_OPERATION_NAME,
|
|
504
509
|
GEN_AI_PROVIDER_NAME,
|
|
505
510
|
GEN_AI_TOOL_NAME,
|
|
511
|
+
// Protocol identity, not content: a still-running MCP call must be
|
|
512
|
+
// distinguishable from a local tool in the live view — the one place
|
|
513
|
+
// setting the marker at creation pays off.
|
|
514
|
+
MCP_METHOD_NAME,
|
|
515
|
+
MCP_PROTOCOL_VERSION,
|
|
506
516
|
// Identity, not content: a pending span must be groupable into its
|
|
507
517
|
// session while still running, that is the live view's whole point.
|
|
508
518
|
SESSION_ID,
|
|
@@ -531,6 +541,9 @@ function renderable(raw, value) {
|
|
|
531
541
|
if (raw instanceof ArrayBuffer) return `<ArrayBuffer ${raw.byteLength} bytes>`;
|
|
532
542
|
return value;
|
|
533
543
|
}
|
|
544
|
+
function asRecord(value) {
|
|
545
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
546
|
+
}
|
|
534
547
|
function toAttributeValue(value) {
|
|
535
548
|
if (typeof value === "string") return truncate(value);
|
|
536
549
|
if (typeof value === "number" || typeof value === "boolean") return value;
|
|
@@ -603,7 +616,10 @@ function creationAttributes(options) {
|
|
|
603
616
|
return attributes;
|
|
604
617
|
}
|
|
605
618
|
function startSpan(name, options = {}) {
|
|
606
|
-
const span = getTracer().startSpan(name, {
|
|
619
|
+
const span = getTracer().startSpan(name, {
|
|
620
|
+
kind: options.otelKind,
|
|
621
|
+
attributes: creationAttributes(options)
|
|
622
|
+
});
|
|
607
623
|
return configure(new Observation(span), options);
|
|
608
624
|
}
|
|
609
625
|
function startAsCurrentSpan(name, optionsOrFn, maybeFn) {
|
|
@@ -613,11 +629,12 @@ function startAsCurrentSpan(name, optionsOrFn, maybeFn) {
|
|
|
613
629
|
creationAttributes(options),
|
|
614
630
|
options.userId,
|
|
615
631
|
(span) => configure(new Observation(span), options),
|
|
616
|
-
fn
|
|
632
|
+
fn,
|
|
633
|
+
options.otelKind
|
|
617
634
|
);
|
|
618
635
|
}
|
|
619
|
-
function runActive(name, attributes, userId, makeHandle, fn) {
|
|
620
|
-
const run = () => getTracer().startActiveSpan(name, { attributes }, async (span) => {
|
|
636
|
+
function runActive(name, attributes, userId, makeHandle, fn, otelKind) {
|
|
637
|
+
const run = () => getTracer().startActiveSpan(name, { kind: otelKind, attributes }, async (span) => {
|
|
621
638
|
const handle = makeHandle(span);
|
|
622
639
|
try {
|
|
623
640
|
return await fn(handle);
|
|
@@ -711,27 +728,25 @@ __export(instrumentationMcp_exports, {
|
|
|
711
728
|
instrumentMcpClient: () => instrumentMcpClient
|
|
712
729
|
});
|
|
713
730
|
function serializeResult(result) {
|
|
714
|
-
|
|
715
|
-
|
|
731
|
+
const record = asRecord(result);
|
|
732
|
+
if (record === void 0) return toAttributeValue(result);
|
|
716
733
|
const structured = record.structured_content ?? record.structuredContent;
|
|
717
734
|
if (structured !== void 0 && structured !== null) return toAttributeValue(structured);
|
|
718
735
|
const content = record.content;
|
|
719
736
|
if (Array.isArray(content)) {
|
|
720
|
-
const texts = content.map(
|
|
721
|
-
(block) => typeof block === "object" && block !== null ? block.text : void 0
|
|
722
|
-
).filter((text) => typeof text === "string");
|
|
737
|
+
const texts = content.map((block) => asRecord(block)?.text).filter((text) => typeof text === "string");
|
|
723
738
|
if (texts.length === 1) return truncate(texts[0]);
|
|
724
739
|
if (texts.length > 1) return toAttributeValue(texts);
|
|
725
740
|
}
|
|
726
741
|
return toAttributeValue(result);
|
|
727
742
|
}
|
|
728
743
|
function resultIsError(result) {
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
return Boolean(record.is_error ?? record.isError);
|
|
744
|
+
const record = asRecord(result);
|
|
745
|
+
return Boolean(record?.is_error ?? record?.isError);
|
|
732
746
|
}
|
|
733
747
|
function recordResult(observation, result) {
|
|
734
|
-
const
|
|
748
|
+
const record = asRecord(result);
|
|
749
|
+
const resultType = record?.result_type ?? record?.resultType;
|
|
735
750
|
if (resultType === INPUT_REQUIRED) {
|
|
736
751
|
observation.setAttribute(MCP_RESULT_TYPE, INPUT_REQUIRED);
|
|
737
752
|
return;
|
|
@@ -742,8 +757,24 @@ function recordResult(observation, result) {
|
|
|
742
757
|
code: import_api3.SpanStatusCode.ERROR,
|
|
743
758
|
message: "tool returned an error result"
|
|
744
759
|
});
|
|
760
|
+
observation.setAttribute(ERROR_TYPE, ERROR_TYPE_TOOL_ERROR);
|
|
745
761
|
}
|
|
746
762
|
}
|
|
763
|
+
function errorType(error) {
|
|
764
|
+
return error instanceof Error ? error.name : typeof error;
|
|
765
|
+
}
|
|
766
|
+
function negotiatedProtocolVersion(client) {
|
|
767
|
+
const version = asRecord(asRecord(client)?.transport)?.protocolVersion;
|
|
768
|
+
return typeof version === "string" ? version : void 0;
|
|
769
|
+
}
|
|
770
|
+
function callAttributes(toolName, protocolVersion) {
|
|
771
|
+
const attributes = {
|
|
772
|
+
[GEN_AI_TOOL_NAME]: toolName,
|
|
773
|
+
[MCP_METHOD_NAME]: MCP_METHOD_TOOLS_CALL
|
|
774
|
+
};
|
|
775
|
+
if (protocolVersion !== void 0) attributes[MCP_PROTOCOL_VERSION] = protocolVersion;
|
|
776
|
+
return attributes;
|
|
777
|
+
}
|
|
747
778
|
function instrumentMcpClient(ClientClass) {
|
|
748
779
|
const current = ClientClass.prototype.callTool;
|
|
749
780
|
const alreadyWrapped = current.riusOriginal;
|
|
@@ -756,15 +787,23 @@ function instrumentMcpClient(ClientClass) {
|
|
|
756
787
|
const instrumented = function instrumentedCallTool(params, ...rest) {
|
|
757
788
|
return startAsCurrentSpan(
|
|
758
789
|
`execute_tool ${params.name}`,
|
|
759
|
-
// Tool name at CREATION: pending snapshots are built at start, so an
|
|
760
|
-
// attribute set inside the callback never reaches them.
|
|
761
790
|
{
|
|
762
791
|
kind: "TOOL" /* TOOL */,
|
|
792
|
+
// The OTel SpanKind FIELD (orthogonal to our taxonomy attribute above):
|
|
793
|
+
// a remote tool call is CLIENT under both the MCP and the GenAI
|
|
794
|
+
// execute-tool conventions.
|
|
795
|
+
otelKind: import_api3.SpanKind.CLIENT,
|
|
763
796
|
input: params.arguments,
|
|
764
|
-
attributes:
|
|
797
|
+
attributes: callAttributes(params.name, negotiatedProtocolVersion(this))
|
|
765
798
|
},
|
|
766
799
|
async (observation) => {
|
|
767
|
-
|
|
800
|
+
let result;
|
|
801
|
+
try {
|
|
802
|
+
result = await original.call(this, params, ...rest);
|
|
803
|
+
} catch (error) {
|
|
804
|
+
observation.setAttribute(ERROR_TYPE, errorType(error));
|
|
805
|
+
throw error;
|
|
806
|
+
}
|
|
768
807
|
recordResult(observation, result);
|
|
769
808
|
return result;
|
|
770
809
|
}
|
|
@@ -1835,7 +1874,7 @@ init_session();
|
|
|
1835
1874
|
init_user();
|
|
1836
1875
|
init_spans();
|
|
1837
1876
|
init_workspace();
|
|
1838
|
-
var VERSION = "0.
|
|
1877
|
+
var VERSION = "0.7.0";
|
|
1839
1878
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1840
1879
|
0 && (module.exports = {
|
|
1841
1880
|
Generation,
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tracer, Span } from '@opentelemetry/api';
|
|
1
|
+
import { Tracer, Span, SpanKind as SpanKind$1 } from '@opentelemetry/api';
|
|
2
2
|
import { SpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
3
3
|
|
|
4
4
|
/** Redacts content attribute values at export. Receives the key when it accepts one. */
|
|
@@ -171,6 +171,13 @@ declare enum SpanKind {
|
|
|
171
171
|
/** Options for {@link startSpan} and {@link startAsCurrentSpan}. */
|
|
172
172
|
interface SpanOptions {
|
|
173
173
|
kind?: SpanKind;
|
|
174
|
+
/**
|
|
175
|
+
* The OpenTelemetry `SpanKind` FIELD (INTERNAL, CLIENT, …), orthogonal to
|
|
176
|
+
* `kind` above, which is our taxonomy attribute. Conventions set it per
|
|
177
|
+
* operation — a remote tool call is CLIENT — so it is opt-in here and left
|
|
178
|
+
* at the tracer's default (INTERNAL) otherwise.
|
|
179
|
+
*/
|
|
180
|
+
otelKind?: SpanKind$1;
|
|
174
181
|
input?: unknown;
|
|
175
182
|
/**
|
|
176
183
|
* End-user identity (`user.id`). Sugar for `withUser`: set on this span at
|
|
@@ -441,6 +448,6 @@ declare function withSession<T>(sessionId: string, fn: (sessionId: string) => T)
|
|
|
441
448
|
*/
|
|
442
449
|
declare function withUser<T>(userId: string, fn: (userId: string) => T): T;
|
|
443
450
|
|
|
444
|
-
declare const VERSION = "0.
|
|
451
|
+
declare const VERSION = "0.7.0";
|
|
445
452
|
|
|
446
453
|
export { Generation, type GenerationBody, type GenerationOptions, type InitOptions, type Mask, Observation, type ObserveOptions, RiusClient, type RiusOptions, type SpanBody, SpanKind, type SpanOptions, VERSION, type WorkspaceExporterFactory, getTracer, init, observe, registerWorkspace, startAsCurrentGeneration, startAsCurrentSpan, startGeneration, startSpan, withSession, withUser, withWorkspace };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Tracer, Span } from '@opentelemetry/api';
|
|
1
|
+
import { Tracer, Span, SpanKind as SpanKind$1 } from '@opentelemetry/api';
|
|
2
2
|
import { SpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
3
3
|
|
|
4
4
|
/** Redacts content attribute values at export. Receives the key when it accepts one. */
|
|
@@ -171,6 +171,13 @@ declare enum SpanKind {
|
|
|
171
171
|
/** Options for {@link startSpan} and {@link startAsCurrentSpan}. */
|
|
172
172
|
interface SpanOptions {
|
|
173
173
|
kind?: SpanKind;
|
|
174
|
+
/**
|
|
175
|
+
* The OpenTelemetry `SpanKind` FIELD (INTERNAL, CLIENT, …), orthogonal to
|
|
176
|
+
* `kind` above, which is our taxonomy attribute. Conventions set it per
|
|
177
|
+
* operation — a remote tool call is CLIENT — so it is opt-in here and left
|
|
178
|
+
* at the tracer's default (INTERNAL) otherwise.
|
|
179
|
+
*/
|
|
180
|
+
otelKind?: SpanKind$1;
|
|
174
181
|
input?: unknown;
|
|
175
182
|
/**
|
|
176
183
|
* End-user identity (`user.id`). Sugar for `withUser`: set on this span at
|
|
@@ -441,6 +448,6 @@ declare function withSession<T>(sessionId: string, fn: (sessionId: string) => T)
|
|
|
441
448
|
*/
|
|
442
449
|
declare function withUser<T>(userId: string, fn: (userId: string) => T): T;
|
|
443
450
|
|
|
444
|
-
declare const VERSION = "0.
|
|
451
|
+
declare const VERSION = "0.7.0";
|
|
445
452
|
|
|
446
453
|
export { Generation, type GenerationBody, type GenerationOptions, type InitOptions, type Mask, Observation, type ObserveOptions, RiusClient, type RiusOptions, type SpanBody, SpanKind, type SpanOptions, VERSION, type WorkspaceExporterFactory, getTracer, init, observe, registerWorkspace, startAsCurrentGeneration, startAsCurrentSpan, startGeneration, startSpan, withSession, withUser, withWorkspace };
|
package/dist/index.js
CHANGED
|
@@ -360,7 +360,7 @@ function kindAttributes(kind) {
|
|
|
360
360
|
if (operation !== void 0) attributes[GEN_AI_OPERATION_NAME] = operation;
|
|
361
361
|
return attributes;
|
|
362
362
|
}
|
|
363
|
-
var TRACER_NAME, SERVICE_INSTANCE_ID, OPENINFERENCE_SPAN_KIND, INPUT_VALUE, OUTPUT_VALUE, SESSION_ID, USER_ID, WORKSPACE_ROUTE, GEN_AI_OPERATION_NAME, GEN_AI_PROVIDER_NAME, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_REASONING_LEVEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_CACHE_WRITE_INPUT_TOKENS, GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, GEN_AI_INPUT_MESSAGES, GEN_AI_OUTPUT_MESSAGES, GEN_AI_RESPONSE_FINISH_REASONS, GEN_AI_TOOL_NAME, GEN_AI_TOOL_DEFINITIONS, GEN_AI_REQUEST_PREFIX, MCP_RESULT_TYPE, GEN_AI_FIRST_TOKEN_EVENT, SpanKind, OPERATION_BY_KIND, CONTENT_ATTRIBUTES, LLM_INVOCATION_PARAMETERS, INVOCATION_PARAMETERS_CONTENT_MEMBERS, CONTENT_ATTRIBUTE_PREFIXES, CONTENT_ATTRIBUTE_SUFFIXES, GLASSFLOW_SPAN_PENDING, PENDING_IDENTITY_ATTRIBUTES, PENDING_IDENTITY_PREFIXES;
|
|
363
|
+
var TRACER_NAME, SERVICE_INSTANCE_ID, OPENINFERENCE_SPAN_KIND, INPUT_VALUE, OUTPUT_VALUE, SESSION_ID, USER_ID, WORKSPACE_ROUTE, GEN_AI_OPERATION_NAME, GEN_AI_PROVIDER_NAME, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_REASONING_LEVEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_CACHE_WRITE_INPUT_TOKENS, GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, GEN_AI_INPUT_MESSAGES, GEN_AI_OUTPUT_MESSAGES, GEN_AI_RESPONSE_FINISH_REASONS, GEN_AI_TOOL_NAME, GEN_AI_TOOL_DEFINITIONS, GEN_AI_REQUEST_PREFIX, MCP_METHOD_NAME, MCP_METHOD_TOOLS_CALL, MCP_PROTOCOL_VERSION, ERROR_TYPE, ERROR_TYPE_TOOL_ERROR, MCP_RESULT_TYPE, GEN_AI_FIRST_TOKEN_EVENT, SpanKind, OPERATION_BY_KIND, CONTENT_ATTRIBUTES, LLM_INVOCATION_PARAMETERS, INVOCATION_PARAMETERS_CONTENT_MEMBERS, CONTENT_ATTRIBUTE_PREFIXES, CONTENT_ATTRIBUTE_SUFFIXES, GLASSFLOW_SPAN_PENDING, PENDING_IDENTITY_ATTRIBUTES, PENDING_IDENTITY_PREFIXES;
|
|
364
364
|
var init_semconv = __esm({
|
|
365
365
|
"src/semconv.ts"() {
|
|
366
366
|
"use strict";
|
|
@@ -389,6 +389,11 @@ var init_semconv = __esm({
|
|
|
389
389
|
GEN_AI_TOOL_NAME = "gen_ai.tool.name";
|
|
390
390
|
GEN_AI_TOOL_DEFINITIONS = "gen_ai.tool.definitions";
|
|
391
391
|
GEN_AI_REQUEST_PREFIX = "gen_ai.request.";
|
|
392
|
+
MCP_METHOD_NAME = "mcp.method.name";
|
|
393
|
+
MCP_METHOD_TOOLS_CALL = "tools/call";
|
|
394
|
+
MCP_PROTOCOL_VERSION = "mcp.protocol.version";
|
|
395
|
+
ERROR_TYPE = "error.type";
|
|
396
|
+
ERROR_TYPE_TOOL_ERROR = "tool_error";
|
|
392
397
|
MCP_RESULT_TYPE = "mcp.result_type";
|
|
393
398
|
GEN_AI_FIRST_TOKEN_EVENT = "gen_ai.first_token";
|
|
394
399
|
SpanKind = /* @__PURE__ */ ((SpanKind2) => {
|
|
@@ -490,6 +495,11 @@ var init_semconv = __esm({
|
|
|
490
495
|
GEN_AI_OPERATION_NAME,
|
|
491
496
|
GEN_AI_PROVIDER_NAME,
|
|
492
497
|
GEN_AI_TOOL_NAME,
|
|
498
|
+
// Protocol identity, not content: a still-running MCP call must be
|
|
499
|
+
// distinguishable from a local tool in the live view — the one place
|
|
500
|
+
// setting the marker at creation pays off.
|
|
501
|
+
MCP_METHOD_NAME,
|
|
502
|
+
MCP_PROTOCOL_VERSION,
|
|
493
503
|
// Identity, not content: a pending span must be groupable into its
|
|
494
504
|
// session while still running, that is the live view's whole point.
|
|
495
505
|
SESSION_ID,
|
|
@@ -518,6 +528,9 @@ function renderable(raw, value) {
|
|
|
518
528
|
if (raw instanceof ArrayBuffer) return `<ArrayBuffer ${raw.byteLength} bytes>`;
|
|
519
529
|
return value;
|
|
520
530
|
}
|
|
531
|
+
function asRecord(value) {
|
|
532
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
533
|
+
}
|
|
521
534
|
function toAttributeValue(value) {
|
|
522
535
|
if (typeof value === "string") return truncate(value);
|
|
523
536
|
if (typeof value === "number" || typeof value === "boolean") return value;
|
|
@@ -591,7 +604,10 @@ function creationAttributes(options) {
|
|
|
591
604
|
return attributes;
|
|
592
605
|
}
|
|
593
606
|
function startSpan(name, options = {}) {
|
|
594
|
-
const span = getTracer().startSpan(name, {
|
|
607
|
+
const span = getTracer().startSpan(name, {
|
|
608
|
+
kind: options.otelKind,
|
|
609
|
+
attributes: creationAttributes(options)
|
|
610
|
+
});
|
|
595
611
|
return configure(new Observation(span), options);
|
|
596
612
|
}
|
|
597
613
|
function startAsCurrentSpan(name, optionsOrFn, maybeFn) {
|
|
@@ -601,11 +617,12 @@ function startAsCurrentSpan(name, optionsOrFn, maybeFn) {
|
|
|
601
617
|
creationAttributes(options),
|
|
602
618
|
options.userId,
|
|
603
619
|
(span) => configure(new Observation(span), options),
|
|
604
|
-
fn
|
|
620
|
+
fn,
|
|
621
|
+
options.otelKind
|
|
605
622
|
);
|
|
606
623
|
}
|
|
607
|
-
function runActive(name, attributes, userId, makeHandle, fn) {
|
|
608
|
-
const run = () => getTracer().startActiveSpan(name, { attributes }, async (span) => {
|
|
624
|
+
function runActive(name, attributes, userId, makeHandle, fn, otelKind) {
|
|
625
|
+
const run = () => getTracer().startActiveSpan(name, { kind: otelKind, attributes }, async (span) => {
|
|
609
626
|
const handle = makeHandle(span);
|
|
610
627
|
try {
|
|
611
628
|
return await fn(handle);
|
|
@@ -697,29 +714,27 @@ var instrumentationMcp_exports = {};
|
|
|
697
714
|
__export(instrumentationMcp_exports, {
|
|
698
715
|
instrumentMcpClient: () => instrumentMcpClient
|
|
699
716
|
});
|
|
700
|
-
import { SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
|
|
717
|
+
import { SpanKind as OtelSpanKind, SpanStatusCode as SpanStatusCode2 } from "@opentelemetry/api";
|
|
701
718
|
function serializeResult(result) {
|
|
702
|
-
|
|
703
|
-
|
|
719
|
+
const record = asRecord(result);
|
|
720
|
+
if (record === void 0) return toAttributeValue(result);
|
|
704
721
|
const structured = record.structured_content ?? record.structuredContent;
|
|
705
722
|
if (structured !== void 0 && structured !== null) return toAttributeValue(structured);
|
|
706
723
|
const content = record.content;
|
|
707
724
|
if (Array.isArray(content)) {
|
|
708
|
-
const texts = content.map(
|
|
709
|
-
(block) => typeof block === "object" && block !== null ? block.text : void 0
|
|
710
|
-
).filter((text) => typeof text === "string");
|
|
725
|
+
const texts = content.map((block) => asRecord(block)?.text).filter((text) => typeof text === "string");
|
|
711
726
|
if (texts.length === 1) return truncate(texts[0]);
|
|
712
727
|
if (texts.length > 1) return toAttributeValue(texts);
|
|
713
728
|
}
|
|
714
729
|
return toAttributeValue(result);
|
|
715
730
|
}
|
|
716
731
|
function resultIsError(result) {
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
return Boolean(record.is_error ?? record.isError);
|
|
732
|
+
const record = asRecord(result);
|
|
733
|
+
return Boolean(record?.is_error ?? record?.isError);
|
|
720
734
|
}
|
|
721
735
|
function recordResult(observation, result) {
|
|
722
|
-
const
|
|
736
|
+
const record = asRecord(result);
|
|
737
|
+
const resultType = record?.result_type ?? record?.resultType;
|
|
723
738
|
if (resultType === INPUT_REQUIRED) {
|
|
724
739
|
observation.setAttribute(MCP_RESULT_TYPE, INPUT_REQUIRED);
|
|
725
740
|
return;
|
|
@@ -730,8 +745,24 @@ function recordResult(observation, result) {
|
|
|
730
745
|
code: SpanStatusCode2.ERROR,
|
|
731
746
|
message: "tool returned an error result"
|
|
732
747
|
});
|
|
748
|
+
observation.setAttribute(ERROR_TYPE, ERROR_TYPE_TOOL_ERROR);
|
|
733
749
|
}
|
|
734
750
|
}
|
|
751
|
+
function errorType(error) {
|
|
752
|
+
return error instanceof Error ? error.name : typeof error;
|
|
753
|
+
}
|
|
754
|
+
function negotiatedProtocolVersion(client) {
|
|
755
|
+
const version = asRecord(asRecord(client)?.transport)?.protocolVersion;
|
|
756
|
+
return typeof version === "string" ? version : void 0;
|
|
757
|
+
}
|
|
758
|
+
function callAttributes(toolName, protocolVersion) {
|
|
759
|
+
const attributes = {
|
|
760
|
+
[GEN_AI_TOOL_NAME]: toolName,
|
|
761
|
+
[MCP_METHOD_NAME]: MCP_METHOD_TOOLS_CALL
|
|
762
|
+
};
|
|
763
|
+
if (protocolVersion !== void 0) attributes[MCP_PROTOCOL_VERSION] = protocolVersion;
|
|
764
|
+
return attributes;
|
|
765
|
+
}
|
|
735
766
|
function instrumentMcpClient(ClientClass) {
|
|
736
767
|
const current = ClientClass.prototype.callTool;
|
|
737
768
|
const alreadyWrapped = current.riusOriginal;
|
|
@@ -744,15 +775,23 @@ function instrumentMcpClient(ClientClass) {
|
|
|
744
775
|
const instrumented = function instrumentedCallTool(params, ...rest) {
|
|
745
776
|
return startAsCurrentSpan(
|
|
746
777
|
`execute_tool ${params.name}`,
|
|
747
|
-
// Tool name at CREATION: pending snapshots are built at start, so an
|
|
748
|
-
// attribute set inside the callback never reaches them.
|
|
749
778
|
{
|
|
750
779
|
kind: "TOOL" /* TOOL */,
|
|
780
|
+
// The OTel SpanKind FIELD (orthogonal to our taxonomy attribute above):
|
|
781
|
+
// a remote tool call is CLIENT under both the MCP and the GenAI
|
|
782
|
+
// execute-tool conventions.
|
|
783
|
+
otelKind: OtelSpanKind.CLIENT,
|
|
751
784
|
input: params.arguments,
|
|
752
|
-
attributes:
|
|
785
|
+
attributes: callAttributes(params.name, negotiatedProtocolVersion(this))
|
|
753
786
|
},
|
|
754
787
|
async (observation) => {
|
|
755
|
-
|
|
788
|
+
let result;
|
|
789
|
+
try {
|
|
790
|
+
result = await original.call(this, params, ...rest);
|
|
791
|
+
} catch (error) {
|
|
792
|
+
observation.setAttribute(ERROR_TYPE, errorType(error));
|
|
793
|
+
throw error;
|
|
794
|
+
}
|
|
756
795
|
recordResult(observation, result);
|
|
757
796
|
return result;
|
|
758
797
|
}
|
|
@@ -1806,7 +1845,7 @@ init_session();
|
|
|
1806
1845
|
init_user();
|
|
1807
1846
|
init_spans();
|
|
1808
1847
|
init_workspace();
|
|
1809
|
-
var VERSION = "0.
|
|
1848
|
+
var VERSION = "0.7.0";
|
|
1810
1849
|
export {
|
|
1811
1850
|
Generation,
|
|
1812
1851
|
Observation,
|