chore(vendor): import pi 0.85.1
Imported as a linear vendor commit so forge rebases do not replay the upstream root tree. git-subtree-dir: third_party/pi git-subtree-split: d981de1229ef899957bbe968bc8dcda02a21f477
This commit is contained in:
635
third_party/pi/packages/agent/src/harness/telemetry.ts
vendored
Normal file
635
third_party/pi/packages/agent/src/harness/telemetry.ts
vendored
Normal file
@@ -0,0 +1,635 @@
|
||||
import type {
|
||||
ExactTelemetryAttributes,
|
||||
SchemaTelemetrySpan,
|
||||
TelemetrySchemaDefinition,
|
||||
TelemetrySchemaSpanEndAttributes,
|
||||
TelemetrySchemaSpanEventAttributes,
|
||||
TelemetrySchemaSpanEventName,
|
||||
TelemetrySchemaSpanName,
|
||||
TelemetrySchemaSpanStartAttributes,
|
||||
TelemetrySchemaSpanUnion,
|
||||
TelemetrySpan,
|
||||
} from "@earendil-works/pi-telemetry";
|
||||
import { type Context, getTelemetryContext, withTelemetryContext } from "./context.ts";
|
||||
|
||||
export type {
|
||||
AttributeValue,
|
||||
ExactTelemetryAttributes,
|
||||
SchemaTelemetrySpan,
|
||||
SpanAttributes,
|
||||
SpanOptions,
|
||||
SpanStatus,
|
||||
TelemetryAttributeDefinition,
|
||||
TelemetryAttributeMetadata,
|
||||
TelemetryAttributeType,
|
||||
TelemetryContext,
|
||||
TelemetryEventAttributeDefinition,
|
||||
TelemetryEventDefinition,
|
||||
TelemetryParentDefinition,
|
||||
TelemetrySchemaDefinition,
|
||||
TelemetrySchemaSpanEndAttributes,
|
||||
TelemetrySchemaSpanEventAttributes,
|
||||
TelemetrySchemaSpanEventName,
|
||||
TelemetrySchemaSpanName,
|
||||
TelemetrySchemaSpanStartAttributes,
|
||||
TelemetrySchemaSpanUnion,
|
||||
TelemetrySpan,
|
||||
TelemetrySpanDefinition,
|
||||
TelemetryStartAttributeDefinition,
|
||||
TypedSpanStarter,
|
||||
} from "@earendil-works/pi-telemetry";
|
||||
|
||||
export const AI_TELEMETRY_SCHEMA = {
|
||||
version: 1,
|
||||
spans: {
|
||||
"pi.ai.request": {
|
||||
description: "One logical request to an AI provider",
|
||||
parents: { kind: "any" },
|
||||
startAttributes: {
|
||||
"pi.ai.operation": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["stream", "fetch_deferred", "cancel_deferred", "generate_images"],
|
||||
description: "Logical provider operation",
|
||||
},
|
||||
"pi.ai.provider": {
|
||||
type: "string",
|
||||
required: true,
|
||||
description: "Selected provider id",
|
||||
},
|
||||
"pi.ai.model": {
|
||||
type: "string",
|
||||
required: true,
|
||||
description: "Requested model id",
|
||||
},
|
||||
"pi.ai.api": {
|
||||
type: "string",
|
||||
required: true,
|
||||
description: "Provider API id",
|
||||
},
|
||||
"pi.ai.streaming": {
|
||||
type: "boolean",
|
||||
required: true,
|
||||
description: "Whether this operation returns a stream",
|
||||
},
|
||||
"pi.ai.deferred": {
|
||||
type: "boolean",
|
||||
required: false,
|
||||
description: "Whether the operation requests or participates in deferred execution",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.ai.response.model": { type: "string", description: "Concrete response model" },
|
||||
"pi.ai.response.id": {
|
||||
type: "string",
|
||||
cardinality: "high",
|
||||
description: "Provider response id",
|
||||
},
|
||||
"pi.ai.response.stop_reason": {
|
||||
type: "string",
|
||||
values: ["stop", "length", "tool_use", "error", "aborted", "deferred"],
|
||||
description: "Normalized terminal response reason",
|
||||
},
|
||||
"pi.ai.http.status_code": { type: "number", description: "Final HTTP status" },
|
||||
"pi.ai.usage.input_tokens": { type: "number", description: "Reported input tokens" },
|
||||
"pi.ai.usage.output_tokens": { type: "number", description: "Reported output tokens" },
|
||||
"pi.ai.usage.cache_read_tokens": { type: "number", description: "Reported cache-read tokens" },
|
||||
"pi.ai.usage.cache_write_tokens": {
|
||||
type: "number",
|
||||
description: "Reported cache-write tokens",
|
||||
},
|
||||
"pi.ai.usage.reasoning_tokens": { type: "number", description: "Reported reasoning tokens" },
|
||||
"pi.ai.usage.total_tokens": { type: "number", description: "Reported total tokens" },
|
||||
"pi.ai.usage.cost": { type: "number", description: "Reported total cost" },
|
||||
"pi.ai.stream.chunk_count": { type: "number", description: "Streamed update chunk count" },
|
||||
"pi.ai.stream.time_to_first_chunk_ms": {
|
||||
type: "number",
|
||||
description: "Elapsed milliseconds to first update chunk",
|
||||
},
|
||||
"pi.ai.error.type": {
|
||||
type: "string",
|
||||
cardinality: "low",
|
||||
description: "Provider or transport error class",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The operation throws or returns an error result" },
|
||||
},
|
||||
},
|
||||
} as const satisfies TelemetrySchemaDefinition;
|
||||
|
||||
export type AiSpanName = TelemetrySchemaSpanName<typeof AI_TELEMETRY_SCHEMA>;
|
||||
export type AiSpanStartAttributes<Name extends AiSpanName> = TelemetrySchemaSpanStartAttributes<
|
||||
typeof AI_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type AiSpanEndAttributes<Name extends AiSpanName> = TelemetrySchemaSpanEndAttributes<
|
||||
typeof AI_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type AiSpanAttributes<Name extends AiSpanName> = AiSpanStartAttributes<Name> & AiSpanEndAttributes<Name>;
|
||||
export type AiSpanEventName<Name extends AiSpanName> = TelemetrySchemaSpanEventName<typeof AI_TELEMETRY_SCHEMA, Name>;
|
||||
export type AiSpanEventAttributes<
|
||||
Name extends AiSpanName,
|
||||
EventName extends AiSpanEventName<Name>,
|
||||
> = TelemetrySchemaSpanEventAttributes<typeof AI_TELEMETRY_SCHEMA, Name, EventName>;
|
||||
export type AiTelemetrySpan<Name extends AiSpanName> = SchemaTelemetrySpan<typeof AI_TELEMETRY_SCHEMA, Name>;
|
||||
export type AiSpan = TelemetrySchemaSpanUnion<typeof AI_TELEMETRY_SCHEMA>;
|
||||
|
||||
export function startAiSpan<Name extends AiSpanName, const Attributes extends AiSpanStartAttributes<Name>, Result>(
|
||||
name: Name,
|
||||
attributes: ExactTelemetryAttributes<AiSpanStartAttributes<Name>, Attributes>,
|
||||
callback: (span: AiTelemetrySpan<Name>, context: Context) => Result | Promise<Result>,
|
||||
context: Context,
|
||||
): Promise<Result> {
|
||||
return getTelemetryContext(context).startSpan({ name, attributes }, (span) =>
|
||||
callback(span as AiTelemetrySpan<Name>, withTelemetryContext(span, context)),
|
||||
);
|
||||
}
|
||||
|
||||
const HOOK_NAMES = [
|
||||
"before_run",
|
||||
"before_drive",
|
||||
"before_run_end",
|
||||
"transform_context",
|
||||
"before_request",
|
||||
"before_payload",
|
||||
"after_response",
|
||||
"before_tool",
|
||||
"after_tool",
|
||||
"before_compaction",
|
||||
"before_navigation",
|
||||
] as const;
|
||||
|
||||
const EVENT_TYPES = [
|
||||
"run_start",
|
||||
"run_resume",
|
||||
"run_suspend",
|
||||
"operation_abort",
|
||||
"run_end",
|
||||
"fault",
|
||||
"handler_error",
|
||||
"turn_start",
|
||||
"turn_end",
|
||||
"retry_scheduled",
|
||||
"retry_start",
|
||||
"retry_end",
|
||||
"message_start",
|
||||
"message_update",
|
||||
"message_end",
|
||||
"tool_start",
|
||||
"tool_update",
|
||||
"tool_end",
|
||||
"entry_added",
|
||||
"queue_update",
|
||||
"value_update",
|
||||
"config_update",
|
||||
"compaction_start",
|
||||
"compaction_end",
|
||||
"navigation_start",
|
||||
"navigation_end",
|
||||
"lane_created",
|
||||
"usage",
|
||||
] as const;
|
||||
|
||||
const operationStartAttributes = {
|
||||
"pi.session.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Session id",
|
||||
},
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.operation.recovery": {
|
||||
type: "boolean",
|
||||
required: true,
|
||||
description: "Whether this invocation resumes durable work",
|
||||
},
|
||||
} as const;
|
||||
|
||||
const operationErrorAttributes = {
|
||||
"pi.error.code": {
|
||||
type: "string",
|
||||
cardinality: "low",
|
||||
description: "Stable operation error code",
|
||||
},
|
||||
"pi.error.type": {
|
||||
type: "string",
|
||||
cardinality: "low",
|
||||
description: "Low-cardinality operation error class",
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const HARNESS_TELEMETRY_SCHEMA = {
|
||||
version: 1,
|
||||
spans: {
|
||||
"pi.harness.run": {
|
||||
description: "One admitted in-process run invocation",
|
||||
parents: { kind: "root_or_external" },
|
||||
startAttributes: {
|
||||
...operationStartAttributes,
|
||||
"pi.operation.kind": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["run"],
|
||||
description: "Run operation kind",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.operation.outcome": {
|
||||
type: "string",
|
||||
values: ["completed", "aborted", "failed", "suspended"],
|
||||
description: "Run invocation outcome",
|
||||
},
|
||||
...operationErrorAttributes,
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The run fails or throws" },
|
||||
},
|
||||
"pi.harness.compaction": {
|
||||
description: "One admitted in-process manual compaction invocation",
|
||||
parents: { kind: "root_or_external" },
|
||||
startAttributes: {
|
||||
...operationStartAttributes,
|
||||
"pi.operation.kind": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["compaction"],
|
||||
description: "Compaction operation kind",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.operation.outcome": {
|
||||
type: "string",
|
||||
values: ["completed", "declined", "aborted", "failed"],
|
||||
description: "Compaction invocation outcome",
|
||||
},
|
||||
...operationErrorAttributes,
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The compaction fails or throws" },
|
||||
},
|
||||
"pi.harness.navigation": {
|
||||
description: "One admitted in-process navigation invocation",
|
||||
parents: { kind: "root_or_external" },
|
||||
startAttributes: {
|
||||
...operationStartAttributes,
|
||||
"pi.operation.kind": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["navigation"],
|
||||
description: "Navigation operation kind",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.operation.outcome": {
|
||||
type: "string",
|
||||
values: ["completed", "declined", "aborted", "failed"],
|
||||
description: "Navigation invocation outcome",
|
||||
},
|
||||
...operationErrorAttributes,
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The navigation fails or throws" },
|
||||
},
|
||||
"pi.harness.checkpoint": {
|
||||
description: "One run checkpoint",
|
||||
parents: { kind: "spans", spans: ["pi.harness.run"] },
|
||||
startAttributes: {
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.checkpoint.kind": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["normal", "abort_reconcile"],
|
||||
description: "Checkpoint purpose",
|
||||
},
|
||||
},
|
||||
endAttributes: {},
|
||||
status: { default: "ok", errorWhen: "Checkpoint work throws" },
|
||||
},
|
||||
"pi.harness.turn": {
|
||||
description: "One assistant response and its tool batch",
|
||||
parents: { kind: "spans", spans: ["pi.harness.run"] },
|
||||
startAttributes: {
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.turn.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Invocation-local turn id",
|
||||
},
|
||||
},
|
||||
endAttributes: {},
|
||||
status: { default: "ok", errorWhen: "Turn work throws" },
|
||||
},
|
||||
"pi.harness.step": {
|
||||
description: "One durable retry attempt",
|
||||
parents: {
|
||||
kind: "spans",
|
||||
spans: ["pi.harness.turn", "pi.harness.checkpoint", "pi.harness.compaction", "pi.harness.navigation"],
|
||||
},
|
||||
startAttributes: {
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.step.kind": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["assistant", "compaction", "branch_summary"],
|
||||
description: "Retryable step kind",
|
||||
},
|
||||
"pi.step.attempt": {
|
||||
type: "number",
|
||||
required: true,
|
||||
description: "One-based durable attempt number",
|
||||
},
|
||||
"pi.compaction.reason": {
|
||||
type: "string",
|
||||
required: false,
|
||||
values: ["manual", "threshold", "overflow"],
|
||||
description: "Compaction trigger",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.step.outcome": {
|
||||
type: "string",
|
||||
values: ["succeeded", "retry", "failed", "aborted", "deferred", "overflow"],
|
||||
description: "Attempt outcome",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The attempt retries, fails, or throws" },
|
||||
},
|
||||
"pi.harness.tool": {
|
||||
description: "One raw phase-2 tool execution",
|
||||
parents: { kind: "spans", spans: ["pi.harness.turn", "pi.harness.run"] },
|
||||
startAttributes: {
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.turn.id": {
|
||||
type: "string",
|
||||
required: false,
|
||||
cardinality: "high",
|
||||
description: "Invocation-local live turn id",
|
||||
},
|
||||
"pi.tool.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
description: "Tool name",
|
||||
},
|
||||
"pi.tool.call_id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Tool call id",
|
||||
},
|
||||
"pi.tool.replay": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: ["never", "safe"],
|
||||
description: "Declared replay policy",
|
||||
},
|
||||
"pi.tool.recovery": {
|
||||
type: "boolean",
|
||||
required: true,
|
||||
description: "Whether this is recovery execution",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.tool.is_error": {
|
||||
type: "boolean",
|
||||
description: "Whether raw phase-2 execution returned an error",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "Raw phase-2 execution returns an error" },
|
||||
},
|
||||
"pi.harness.hook": {
|
||||
description: "One registered hook handler invocation",
|
||||
parents: { kind: "any" },
|
||||
startAttributes: {
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Lane name",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: false,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id when accepted",
|
||||
},
|
||||
"pi.hook.name": {
|
||||
type: "string",
|
||||
required: true,
|
||||
values: HOOK_NAMES,
|
||||
description: "Hook name",
|
||||
},
|
||||
"pi.hook.registration_id": {
|
||||
type: "string",
|
||||
required: false,
|
||||
description: "Optional hook registration metadata",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.hook.outcome": {
|
||||
type: "string",
|
||||
values: ["completed", "skipped", "blocked", "failed"],
|
||||
description: "Handler outcome",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "The handler throws" },
|
||||
},
|
||||
"pi.harness.sleep": {
|
||||
description: "One retry delay",
|
||||
parents: {
|
||||
kind: "spans",
|
||||
spans: [
|
||||
"pi.harness.run",
|
||||
"pi.harness.compaction",
|
||||
"pi.harness.navigation",
|
||||
"pi.harness.turn",
|
||||
"pi.harness.checkpoint",
|
||||
],
|
||||
},
|
||||
startAttributes: {
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id",
|
||||
},
|
||||
"pi.sleep.delay_ms": {
|
||||
type: "number",
|
||||
required: true,
|
||||
description: "Requested delay in milliseconds",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.sleep.outcome": {
|
||||
type: "string",
|
||||
values: ["elapsed", "aborted"],
|
||||
description: "Delay outcome",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "Sleep work throws" },
|
||||
},
|
||||
"pi.harness.event_handler": {
|
||||
description: "One passive event listener invocation",
|
||||
parents: { kind: "any" },
|
||||
startAttributes: {
|
||||
"pi.event.type": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "low",
|
||||
values: EVENT_TYPES,
|
||||
description: "Delivered harness event type",
|
||||
},
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: false,
|
||||
cardinality: "high",
|
||||
description: "Lane name for lane-scoped events",
|
||||
},
|
||||
},
|
||||
endAttributes: {},
|
||||
status: { default: "ok", errorWhen: "The listener throws" },
|
||||
},
|
||||
"pi.session.write": {
|
||||
description: "One committed session transaction",
|
||||
parents: { kind: "any" },
|
||||
startAttributes: {
|
||||
"pi.session.id": {
|
||||
type: "string",
|
||||
required: true,
|
||||
cardinality: "high",
|
||||
description: "Session id",
|
||||
},
|
||||
"pi.lane.name": {
|
||||
type: "string",
|
||||
required: false,
|
||||
cardinality: "high",
|
||||
description: "Lane name when supplied by the caller",
|
||||
},
|
||||
"pi.operation.id": {
|
||||
type: "string",
|
||||
required: false,
|
||||
cardinality: "high",
|
||||
description: "Durable operation id when supplied by the caller",
|
||||
},
|
||||
"pi.session.item_count": {
|
||||
type: "number",
|
||||
required: true,
|
||||
description: "Number of writes in the transaction",
|
||||
},
|
||||
"pi.session.item_kinds": {
|
||||
type: "string[]",
|
||||
required: true,
|
||||
elementValues: ["entry", "usage", "value", "list"],
|
||||
description: "Distinct write kinds in the transaction",
|
||||
},
|
||||
},
|
||||
endAttributes: {
|
||||
"pi.session.first_seq": {
|
||||
type: "number",
|
||||
description: "First committed sequence in the transaction",
|
||||
},
|
||||
"pi.session.last_seq": {
|
||||
type: "number",
|
||||
description: "Last committed sequence in the transaction",
|
||||
},
|
||||
},
|
||||
status: { default: "ok", errorWhen: "Storage rejects the transaction" },
|
||||
},
|
||||
},
|
||||
} as const satisfies TelemetrySchemaDefinition;
|
||||
|
||||
/** Combined typed span vocabulary for agent-owned AI-request and harness telemetry. */
|
||||
export const AGENT_TELEMETRY_SCHEMAS = [AI_TELEMETRY_SCHEMA, HARNESS_TELEMETRY_SCHEMA] as const;
|
||||
|
||||
export type HarnessSpanName = TelemetrySchemaSpanName<typeof HARNESS_TELEMETRY_SCHEMA>;
|
||||
export type HarnessSpanStartAttributes<Name extends HarnessSpanName> = TelemetrySchemaSpanStartAttributes<
|
||||
typeof HARNESS_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type HarnessSpanEndAttributes<Name extends HarnessSpanName> = TelemetrySchemaSpanEndAttributes<
|
||||
typeof HARNESS_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type HarnessSpanAttributes<Name extends HarnessSpanName> = HarnessSpanStartAttributes<Name> &
|
||||
HarnessSpanEndAttributes<Name>;
|
||||
export type HarnessSpanEventName<Name extends HarnessSpanName> = TelemetrySchemaSpanEventName<
|
||||
typeof HARNESS_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type HarnessSpanEventAttributes<
|
||||
Name extends HarnessSpanName,
|
||||
EventName extends HarnessSpanEventName<Name>,
|
||||
> = TelemetrySchemaSpanEventAttributes<typeof HARNESS_TELEMETRY_SCHEMA, Name, EventName>;
|
||||
export type HarnessTelemetrySpan<Name extends HarnessSpanName> = SchemaTelemetrySpan<
|
||||
typeof HARNESS_TELEMETRY_SCHEMA,
|
||||
Name
|
||||
>;
|
||||
export type HarnessSpan = TelemetrySchemaSpanUnion<typeof HARNESS_TELEMETRY_SCHEMA>;
|
||||
|
||||
export function startHarnessSpan<
|
||||
Name extends HarnessSpanName,
|
||||
const Attributes extends HarnessSpanStartAttributes<Name>,
|
||||
Result,
|
||||
>(
|
||||
name: Name,
|
||||
attributes: ExactTelemetryAttributes<HarnessSpanStartAttributes<Name>, Attributes>,
|
||||
callback: (span: HarnessTelemetrySpan<Name>, context: Context) => Result | Promise<Result>,
|
||||
context: Context,
|
||||
): Promise<Result> {
|
||||
return getTelemetryContext(context).startSpan({ name, attributes }, (span: TelemetrySpan) =>
|
||||
callback(span as HarnessTelemetrySpan<Name>, withTelemetryContext(span, context)),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user