@namzu/sdk 62.13.0 → 62.14.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/agents/file-definitions.d.ts +7 -0
  3. package/dist/agents/file-definitions.d.ts.map +1 -1
  4. package/dist/agents/file-definitions.js +20 -0
  5. package/dist/agents/file-definitions.js.map +1 -1
  6. package/dist/agents/index.d.ts +1 -1
  7. package/dist/agents/index.d.ts.map +1 -1
  8. package/dist/agents/index.js +1 -1
  9. package/dist/agents/index.js.map +1 -1
  10. package/dist/bridge/acp/server.d.ts +8 -1
  11. package/dist/bridge/acp/server.d.ts.map +1 -1
  12. package/dist/bridge/acp/server.js +12 -0
  13. package/dist/bridge/acp/server.js.map +1 -1
  14. package/dist/constants/data-epoch.d.ts +18 -0
  15. package/dist/constants/data-epoch.d.ts.map +1 -0
  16. package/dist/constants/data-epoch.js +18 -0
  17. package/dist/constants/data-epoch.js.map +1 -0
  18. package/dist/constants/index.d.ts +1 -0
  19. package/dist/constants/index.d.ts.map +1 -1
  20. package/dist/constants/index.js +1 -0
  21. package/dist/constants/index.js.map +1 -1
  22. package/dist/constants/telemetry/index.d.ts +12 -0
  23. package/dist/constants/telemetry/index.d.ts.map +1 -1
  24. package/dist/constants/telemetry/index.js +12 -0
  25. package/dist/constants/telemetry/index.js.map +1 -1
  26. package/dist/plugin/index.d.ts +1 -1
  27. package/dist/plugin/index.d.ts.map +1 -1
  28. package/dist/plugin/index.js +1 -1
  29. package/dist/plugin/index.js.map +1 -1
  30. package/dist/plugin/loader.d.ts +11 -0
  31. package/dist/plugin/loader.d.ts.map +1 -1
  32. package/dist/plugin/loader.js +15 -2
  33. package/dist/plugin/loader.js.map +1 -1
  34. package/dist/public-runtime.d.ts +5 -4
  35. package/dist/public-runtime.d.ts.map +1 -1
  36. package/dist/public-runtime.js +6 -3
  37. package/dist/public-runtime.js.map +1 -1
  38. package/dist/runtime/query/cancelled-before-start.d.ts.map +1 -1
  39. package/dist/runtime/query/cancelled-before-start.js +2 -0
  40. package/dist/runtime/query/cancelled-before-start.js.map +1 -1
  41. package/dist/runtime/query/index.d.ts.map +1 -1
  42. package/dist/runtime/query/index.js +2 -0
  43. package/dist/runtime/query/index.js.map +1 -1
  44. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  45. package/dist/runtime/query/iteration/stream-turn.js +5 -0
  46. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  47. package/dist/runtime/query/result.d.ts.map +1 -1
  48. package/dist/runtime/query/result.js +2 -0
  49. package/dist/runtime/query/result.js.map +1 -1
  50. package/dist/skills/index.d.ts +1 -1
  51. package/dist/skills/index.d.ts.map +1 -1
  52. package/dist/skills/index.js +1 -1
  53. package/dist/skills/index.js.map +1 -1
  54. package/dist/skills/loader.d.ts +15 -1
  55. package/dist/skills/loader.d.ts.map +1 -1
  56. package/dist/skills/loader.js +17 -3
  57. package/dist/skills/loader.js.map +1 -1
  58. package/dist/telemetry/genai.d.ts +98 -0
  59. package/dist/telemetry/genai.d.ts.map +1 -0
  60. package/dist/telemetry/genai.js +189 -0
  61. package/dist/telemetry/genai.js.map +1 -0
  62. package/dist/telemetry/runtime-accessors.d.ts +5 -0
  63. package/dist/telemetry/runtime-accessors.d.ts.map +1 -1
  64. package/dist/telemetry/runtime-accessors.js +11 -1
  65. package/dist/telemetry/runtime-accessors.js.map +1 -1
  66. package/dist/toolsets/manager.d.ts.map +1 -1
  67. package/dist/toolsets/manager.js +12 -0
  68. package/dist/toolsets/manager.js.map +1 -1
  69. package/dist/types/acp/index.d.ts +18 -0
  70. package/dist/types/acp/index.d.ts.map +1 -1
  71. package/package.json +1 -1
  72. package/src/agents/file-definitions.ts +21 -0
  73. package/src/agents/index.ts +1 -0
  74. package/src/bridge/acp/server.ts +20 -0
  75. package/src/constants/data-epoch.ts +17 -0
  76. package/src/constants/index.ts +1 -0
  77. package/src/constants/telemetry/index.ts +13 -0
  78. package/src/plugin/index.ts +7 -1
  79. package/src/plugin/loader.ts +16 -2
  80. package/src/public-runtime.ts +17 -0
  81. package/src/runtime/query/cancelled-before-start.ts +2 -0
  82. package/src/runtime/query/index.ts +2 -0
  83. package/src/runtime/query/iteration/stream-turn.ts +10 -0
  84. package/src/runtime/query/result.ts +2 -0
  85. package/src/skills/index.ts +1 -0
  86. package/src/skills/loader.ts +21 -3
  87. package/src/telemetry/genai.ts +202 -0
  88. package/src/telemetry/runtime-accessors.ts +11 -1
  89. package/src/toolsets/manager.ts +22 -0
  90. package/src/types/acp/index.ts +20 -0
@@ -0,0 +1,202 @@
1
+ import type { Attributes } from '@opentelemetry/api'
2
+ import { isProviderRequestError } from '../provider/errors.js'
3
+ import type { TokenUsage } from '../types/common/index.js'
4
+ import { GENAI } from './attributes.js'
5
+
6
+ /**
7
+ * The OpenTelemetry semantic conventions for generative AI, as far as the
8
+ * spans of this kernel follow them.
9
+ *
10
+ * The convention is still marked "Development", so its names can change
11
+ * between releases. What the kernel emits is therefore pinned to ONE released
12
+ * version, and says so: the instrumentation scope carries the schema URL of
13
+ * that version. The text of the convention was published in the
14
+ * `semantic-conventions` repository up to and including v1.41.1; later
15
+ * releases only point to a new repository. Moving the pin means reading the
16
+ * new text, changing {@link GENAI_SEMCONV_VERSION} and the table in
17
+ * `docs/sdk/telemetry-genai.md` together; a test fails when an attribute name
18
+ * is emitted that is not in {@link GENAI_SEMCONV_ATTRIBUTES}.
19
+ *
20
+ * Everything here is additive: the kernel's own names (`namzu.*`, and the
21
+ * `gen_ai.*` names it already wrote) are untouched. One process-wide switch
22
+ * turns the new names off for a backend that bills by attribute.
23
+ */
24
+ export const GENAI_SEMCONV_VERSION = '1.41.1'
25
+
26
+ /** Schema URL of the pinned version; set on the tracer's instrumentation scope. */
27
+ export const GENAI_SEMCONV_SCHEMA_URL = `https://opentelemetry.io/schemas/${GENAI_SEMCONV_VERSION}`
28
+
29
+ /** `gen_ai.operation.name` values this kernel uses; all three are in the pinned convention's list. */
30
+ export const GENAI_OPERATION = {
31
+ CHAT: 'chat',
32
+ EXECUTE_TOOL: 'execute_tool',
33
+ INVOKE_AGENT: 'invoke_agent',
34
+ } as const
35
+
36
+ /** The convention's name for the error class of a failed operation (stable). */
37
+ export const ERROR_TYPE = 'error.type'
38
+
39
+ /** The convention's fallback `error.type` value. */
40
+ export const ERROR_TYPE_OTHER = '_OTHER'
41
+
42
+ /**
43
+ * Every attribute name the pinned convention version defines for the three
44
+ * span kinds this kernel emits (inference, execute tool, invoke agent) that
45
+ * the kernel may write, whether the kernel's own earlier code or the additions
46
+ * wrote it. A span's `gen_ai.*` / `error.type` keys must all be in here, with
47
+ * the one exception named in {@link GENAI_NON_CONVENTION_NAMES}.
48
+ */
49
+ export const GENAI_SEMCONV_ATTRIBUTES: readonly string[] = [
50
+ GENAI.OPERATION_NAME,
51
+ GENAI.PROVIDER_NAME,
52
+ ERROR_TYPE,
53
+ GENAI.CONVERSATION_ID,
54
+ GENAI.AGENT_NAME,
55
+ GENAI.AGENT_ID,
56
+ GENAI.REQUEST_MODEL,
57
+ GENAI.REQUEST_STREAM,
58
+ GENAI.REQUEST_TEMPERATURE,
59
+ GENAI.REQUEST_MAX_TOKENS,
60
+ GENAI.RESPONSE_MODEL,
61
+ GENAI.RESPONSE_ID,
62
+ GENAI.RESPONSE_FINISH_REASONS,
63
+ GENAI.USAGE_INPUT_TOKENS,
64
+ GENAI.USAGE_OUTPUT_TOKENS,
65
+ GENAI.USAGE_CACHE_READ_INPUT_TOKENS,
66
+ GENAI.USAGE_CACHE_CREATION_INPUT_TOKENS,
67
+ GENAI.USAGE_REASONING_OUTPUT_TOKENS,
68
+ GENAI.TOOL_NAME,
69
+ GENAI.TOOL_CALL_ID,
70
+ GENAI.TOOL_TYPE,
71
+ ]
72
+
73
+ /**
74
+ * `gen_ai.*` names the kernel writes that are NOT in the pinned convention.
75
+ * `gen_ai.system` is still in the 1.41.1 registry but deprecated, replaced by
76
+ * `gen_ai.provider.name`; the kernel emits it deliberately and
77
+ * it stays because it is existing output that nothing may remove.
78
+ */
79
+ export const GENAI_NON_CONVENTION_NAMES: readonly string[] = [GENAI.SYSTEM]
80
+
81
+ let enabled = true
82
+
83
+ /**
84
+ * Turn the convention's attribute names (and the schema URL) on or off for
85
+ * every span the kernel starts from now on. On by default. `@namzu/telemetry`
86
+ * calls this from `TelemetryConfig.genAiAttributes`; a host that does not use
87
+ * that package can call it directly.
88
+ */
89
+ export function setGenAiConventions(on: boolean): void {
90
+ enabled = on
91
+ }
92
+
93
+ export function genAiConventionsEnabled(): boolean {
94
+ return enabled
95
+ }
96
+
97
+ /**
98
+ * The value for `gen_ai.provider.name`, which the convention requires on every
99
+ * span that carries it.
100
+ *
101
+ * The convention (1.41.1) says: "If one of them applies, then the respective
102
+ * value MUST be used; otherwise, a custom value MAY be used." and states no
103
+ * further rule on the form of a custom value. So:
104
+ *
105
+ * - a listed value only when our provider IS that vendor's own API (the
106
+ * cases below; `google` is `gcp.gen_ai`, "Any Google generative AI
107
+ * endpoint", since our id does not say which one);
108
+ * - otherwise our own provider id, lower case, as the custom value. A gateway
109
+ * that forwards to several vendors, a local runner and a custom HTTP
110
+ * endpoint are never mapped to a vendor they are not.
111
+ *
112
+ * `undefined` only when there is no provider id at all.
113
+ */
114
+ export function genAiProviderName(providerId: string | undefined): string | undefined {
115
+ switch (providerId) {
116
+ case 'anthropic':
117
+ return 'anthropic'
118
+ case 'bedrock':
119
+ return 'aws.bedrock'
120
+ case 'deepseek':
121
+ return 'deepseek'
122
+ case 'google':
123
+ return 'gcp.gen_ai'
124
+ case 'openai':
125
+ case 'codex':
126
+ return 'openai'
127
+ default: {
128
+ const own = providerId?.trim().toLowerCase()
129
+ return own ? own : undefined
130
+ }
131
+ }
132
+ }
133
+
134
+ /**
135
+ * A low-cardinality class for a failure, for `error.type`: the provider
136
+ * error kind for a classified provider failure, the error's own class name
137
+ * for an exception, `_OTHER` for anything else (a thrown string, a plain
138
+ * `Error`).
139
+ */
140
+ export function genAiErrorType(err: unknown): string {
141
+ if (isProviderRequestError(err)) return err.kind
142
+ if (err instanceof Error) {
143
+ const name = err.name
144
+ return name && name !== 'Error' ? name : ERROR_TYPE_OTHER
145
+ }
146
+ return ERROR_TYPE_OTHER
147
+ }
148
+
149
+ /** Added when a turn (an agent run, a sub-agent included) starts. */
150
+ export function agentRunAttributes(providerId: string | undefined): Attributes {
151
+ if (!enabled) return {}
152
+ const provider = genAiProviderName(providerId)
153
+ return {
154
+ [GENAI.OPERATION_NAME]: GENAI_OPERATION.INVOKE_AGENT,
155
+ ...(provider !== undefined ? { [GENAI.PROVIDER_NAME]: provider } : {}),
156
+ }
157
+ }
158
+
159
+ /** Added when a model call starts. Every model call is streamed. */
160
+ export function chatStartAttributes(providerId: string | undefined): Attributes {
161
+ if (!enabled) return {}
162
+ const provider = genAiProviderName(providerId)
163
+ return {
164
+ ...(provider !== undefined ? { [GENAI.PROVIDER_NAME]: provider } : {}),
165
+ [GENAI.REQUEST_STREAM]: true,
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Added when a model call answers. A count is written only when the driver
171
+ * reported a positive one: the record cannot tell "none" from "not
172
+ * reported", so a zero is left out rather than stated.
173
+ */
174
+ export function chatUsageAttributes(usage: TokenUsage): Attributes {
175
+ if (!enabled) return {}
176
+ return {
177
+ ...(usage.cachedTokens > 0
178
+ ? { [GENAI.USAGE_CACHE_READ_INPUT_TOKENS]: usage.cachedTokens }
179
+ : {}),
180
+ ...(usage.cacheWriteTokens > 0
181
+ ? { [GENAI.USAGE_CACHE_CREATION_INPUT_TOKENS]: usage.cacheWriteTokens }
182
+ : {}),
183
+ ...(usage.reasoningTokens !== undefined && usage.reasoningTokens > 0
184
+ ? { [GENAI.USAGE_REASONING_OUTPUT_TOKENS]: usage.reasoningTokens }
185
+ : {}),
186
+ }
187
+ }
188
+
189
+ /** Added when a tool call starts. */
190
+ export function toolCallAttributes(): Attributes {
191
+ if (!enabled) return {}
192
+ return { [GENAI.OPERATION_NAME]: GENAI_OPERATION.EXECUTE_TOOL }
193
+ }
194
+
195
+ /** The `error.type` of a tool call the kernel refused (not available, not allowed, plan mode); a custom low-cardinality value, which the convention allows. */
196
+ export const PERMISSION_DENIED = 'permission_denied'
197
+
198
+ /** Added to a span whose operation ended in an error. */
199
+ export function errorTypeAttributes(errorType: string): Attributes {
200
+ if (!enabled) return {}
201
+ return { [ERROR_TYPE]: errorType }
202
+ }
@@ -9,9 +9,19 @@
9
9
  // discarded — standard OTEL library behavior.
10
10
 
11
11
  import { type SpanContext, type Tracer, context, trace } from '@opentelemetry/api'
12
+ import { GENAI_SEMCONV_SCHEMA_URL, genAiConventionsEnabled } from './genai.js'
12
13
 
14
+ /**
15
+ * The kernel's tracer. While the GenAI convention names are on, its
16
+ * instrumentation scope carries the schema URL of the pinned convention
17
+ * version, which is how the convention says a producer states the version.
18
+ */
13
19
  export function getTracer(): Tracer {
14
- return trace.getTracer('namzu')
20
+ return genAiConventionsEnabled()
21
+ ? trace
22
+ .getTracerProvider()
23
+ .getTracer('namzu', undefined, { schemaUrl: GENAI_SEMCONV_SCHEMA_URL })
24
+ : trace.getTracer('namzu')
15
25
  }
16
26
 
17
27
  /**
@@ -6,6 +6,13 @@ import { assertToolName, describeWithOutput, toolDiscoveryHint } from '../regist
6
6
  import { renderToolSchema, toolWireSchema } from '../registry/tool/schema.js'
7
7
  import { ToolResultHalted, screenToolResult } from '../registry/tool/screen.js'
8
8
  import { GENAI, NAMZU, toolSpanName } from '../telemetry/attributes.js'
9
+ import {
10
+ ERROR_TYPE_OTHER,
11
+ PERMISSION_DENIED,
12
+ errorTypeAttributes,
13
+ genAiErrorType,
14
+ toolCallAttributes,
15
+ } from '../telemetry/genai.js'
9
16
  import { recordToolCall } from '../telemetry/metrics.js'
10
17
  import { getTracer } from '../telemetry/runtime-accessors.js'
11
18
  import { failureFactsFromError } from '../tools/failure-facts.js'
@@ -804,6 +811,8 @@ Executable tool names, descriptions, and JSON input schemas are attached through
804
811
  [GENAI.TOOL_TYPE]: 'function',
805
812
  ...(context.toolUseId !== undefined ? { [GENAI.TOOL_CALL_ID]: context.toolUseId } : {}),
806
813
  ...toolSpanIdentity(context),
814
+ ...toolCallAttributes(),
815
+ ...errorTypeAttributes(genAiErrorType(err)),
807
816
  [NAMZU.TOOL_SUCCESS]: false,
808
817
  [NAMZU.TOOL_ERROR]: toErrorMessage(err),
809
818
  })
@@ -841,6 +850,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
841
850
  [GENAI.TOOL_TYPE]: 'function',
842
851
  ...(context.toolUseId !== undefined ? { [GENAI.TOOL_CALL_ID]: context.toolUseId } : {}),
843
852
  ...toolSpanIdentity(context),
853
+ ...toolCallAttributes(),
844
854
  })
845
855
 
846
856
  // The permitted `this.getAvailability` substitution: derived,
@@ -852,6 +862,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
852
862
  span.setAttributes({
853
863
  [NAMZU.TOOL_SUCCESS]: false,
854
864
  [NAMZU.TOOL_ERROR]: msg,
865
+ ...errorTypeAttributes(ERROR_TYPE_OTHER),
855
866
  })
856
867
  span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
857
868
  return {
@@ -871,6 +882,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
871
882
  span.setAttributes({
872
883
  [NAMZU.TOOL_SUCCESS]: false,
873
884
  [NAMZU.TOOL_ERROR]: msg,
885
+ ...errorTypeAttributes(PERMISSION_DENIED),
874
886
  })
875
887
  span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
876
888
  return {
@@ -889,6 +901,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
889
901
  span.setAttributes({
890
902
  [NAMZU.TOOL_SUCCESS]: false,
891
903
  [NAMZU.TOOL_ERROR]: msg,
904
+ ...errorTypeAttributes(PERMISSION_DENIED),
892
905
  })
893
906
  span.setStatus({ code: SpanStatusCode.ERROR, message: msg })
894
907
  return {
@@ -932,6 +945,13 @@ Executable tool names, descriptions, and JSON input schemas are attached through
932
945
  )
933
946
  if (!result.success && result.error) {
934
947
  span.setAttribute(NAMZU.TOOL_ERROR, result.error)
948
+ span.setAttributes(
949
+ errorTypeAttributes(
950
+ 'permissionDenied' in result && result.permissionDenied
951
+ ? PERMISSION_DENIED
952
+ : ERROR_TYPE_OTHER,
953
+ ),
954
+ )
935
955
  span.setStatus({
936
956
  code: SpanStatusCode.ERROR,
937
957
  message: result.error,
@@ -946,6 +966,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
946
966
  span.setAttributes({
947
967
  [NAMZU.TOOL_SUCCESS]: false,
948
968
  [NAMZU.TOOL_ERROR]: err.message,
969
+ ...errorTypeAttributes(genAiErrorType(err)),
949
970
  })
950
971
  span.setStatus({
951
972
  code: SpanStatusCode.ERROR,
@@ -962,6 +983,7 @@ Executable tool names, descriptions, and JSON input schemas are attached through
962
983
  span.setAttributes({
963
984
  [NAMZU.TOOL_SUCCESS]: false,
964
985
  [NAMZU.TOOL_ERROR]: errorMessage,
986
+ ...errorTypeAttributes(genAiErrorType(err)),
965
987
  })
966
988
  span.setStatus({
967
989
  code: SpanStatusCode.ERROR,
@@ -38,7 +38,27 @@ export interface AcpInitializeParams extends AcpClientCapabilities {
38
38
  readonly clientInfo?: { readonly name?: string; readonly version?: string }
39
39
  }
40
40
 
41
+ /**
42
+ * What a host says about the engine it runs, in `initialize`. A reader that
43
+ * does not know this object ignores it.
44
+ */
45
+ export interface AcpKernelFacts {
46
+ /** The engine's own version (this package's). */
47
+ readonly engine: string
48
+ /** The data epoch of the on-disk formats this engine writes. */
49
+ readonly dataEpoch: number
50
+ /** The version of the application that hosts the engine, when that application says one. */
51
+ readonly commandLine?: string
52
+ /** The contract number an installed client application checks, when the host was started for one. */
53
+ readonly desktopContract?: number
54
+ }
55
+
56
+ /** The two facts a host application adds to `AcpKernelFacts`; the engine states the rest itself. */
57
+ export type AcpHostKernelFacts = Pick<AcpKernelFacts, 'commandLine' | 'desktopContract'>
58
+
41
59
  export interface AcpInitializeResult {
60
+ /** The engine and data facts a client may use to decide whether this host is safe for it. */
61
+ readonly kernel?: AcpKernelFacts
42
62
  /** True only when the host gateway opts into inline user attachment delivery. */
43
63
  readonly promptAttachments?: boolean
44
64
  /** True only when this host applies captured effort and review settings per prompt. */