@earendil-works/pi-ai 1.3.0 → 1.5.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 (304) hide show
  1. package/README.md +113 -38
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +66 -81
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  6. package/dist/api/azure-openai-responses.js +8 -10
  7. package/dist/api/azure-openai-responses.js.map +1 -1
  8. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  9. package/dist/api/bedrock-converse-stream.js +137 -103
  10. package/dist/api/bedrock-converse-stream.js.map +1 -1
  11. package/dist/api/classifier-shared.d.ts.map +1 -1
  12. package/dist/api/classifier-shared.js +4 -3
  13. package/dist/api/classifier-shared.js.map +1 -1
  14. package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
  15. package/dist/api/cloudflare-workers-ai-system-one.js +8 -0
  16. package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
  17. package/dist/api/constrained-sampling.d.ts +15 -1
  18. package/dist/api/constrained-sampling.d.ts.map +1 -1
  19. package/dist/api/constrained-sampling.js +51 -18
  20. package/dist/api/constrained-sampling.js.map +1 -1
  21. package/dist/api/google-generative-ai.d.ts.map +1 -1
  22. package/dist/api/google-generative-ai.js +4 -10
  23. package/dist/api/google-generative-ai.js.map +1 -1
  24. package/dist/api/google-shared.d.ts +2 -1
  25. package/dist/api/google-shared.d.ts.map +1 -1
  26. package/dist/api/google-shared.js +58 -3
  27. package/dist/api/google-shared.js.map +1 -1
  28. package/dist/api/google-vertex.d.ts.map +1 -1
  29. package/dist/api/google-vertex.js +9 -15
  30. package/dist/api/google-vertex.js.map +1 -1
  31. package/dist/api/lazy.d.ts +7 -2
  32. package/dist/api/lazy.d.ts.map +1 -1
  33. package/dist/api/lazy.js +24 -5
  34. package/dist/api/lazy.js.map +1 -1
  35. package/dist/api/llama-cpp-classify.d.ts.map +1 -1
  36. package/dist/api/llama-cpp-classify.js +2 -1
  37. package/dist/api/llama-cpp-classify.js.map +1 -1
  38. package/dist/api/mistral-conversations.d.ts.map +1 -1
  39. package/dist/api/mistral-conversations.js +19 -46
  40. package/dist/api/mistral-conversations.js.map +1 -1
  41. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  42. package/dist/api/openai-codex-responses.js +17 -16
  43. package/dist/api/openai-codex-responses.js.map +1 -1
  44. package/dist/api/openai-completions.d.ts.map +1 -1
  45. package/dist/api/openai-completions.js +56 -62
  46. package/dist/api/openai-completions.js.map +1 -1
  47. package/dist/api/openai-responses-shared.d.ts +16 -0
  48. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  49. package/dist/api/openai-responses-shared.js +119 -66
  50. package/dist/api/openai-responses-shared.js.map +1 -1
  51. package/dist/api/openai-responses.d.ts.map +1 -1
  52. package/dist/api/openai-responses.js +17 -15
  53. package/dist/api/openai-responses.js.map +1 -1
  54. package/dist/api/openrouter-images.d.ts.map +1 -1
  55. package/dist/api/openrouter-images.js +5 -3
  56. package/dist/api/openrouter-images.js.map +1 -1
  57. package/dist/api/pi-messages.d.ts +2 -0
  58. package/dist/api/pi-messages.d.ts.map +1 -1
  59. package/dist/api/pi-messages.js +27 -12
  60. package/dist/api/pi-messages.js.map +1 -1
  61. package/dist/api/simple-options.d.ts.map +1 -1
  62. package/dist/api/simple-options.js +2 -1
  63. package/dist/api/simple-options.js.map +1 -1
  64. package/dist/api/system-one-shared.d.ts +29 -2
  65. package/dist/api/system-one-shared.d.ts.map +1 -1
  66. package/dist/api/system-one-shared.js +55 -3
  67. package/dist/api/system-one-shared.js.map +1 -1
  68. package/dist/api/typesafe-system-one.d.ts.map +1 -1
  69. package/dist/api/typesafe-system-one.js +10 -0
  70. package/dist/api/typesafe-system-one.js.map +1 -1
  71. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  72. package/dist/auth/oauth/github-copilot.js +4 -11
  73. package/dist/auth/oauth/github-copilot.js.map +1 -1
  74. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  75. package/dist/auth/oauth/kimi-coding.js +4 -22
  76. package/dist/auth/oauth/kimi-coding.js.map +1 -1
  77. package/dist/auth/oauth/meta.d.ts.map +1 -1
  78. package/dist/auth/oauth/meta.js +1 -14
  79. package/dist/auth/oauth/meta.js.map +1 -1
  80. package/dist/auth/oauth/radius.d.ts.map +1 -1
  81. package/dist/auth/oauth/radius.js +9 -3
  82. package/dist/auth/oauth/radius.js.map +1 -1
  83. package/dist/auth/oauth/trusted-url.d.ts +7 -0
  84. package/dist/auth/oauth/trusted-url.d.ts.map +1 -0
  85. package/dist/auth/oauth/trusted-url.js +12 -0
  86. package/dist/auth/oauth/trusted-url.js.map +1 -0
  87. package/dist/auth/types.d.ts +4 -0
  88. package/dist/auth/types.d.ts.map +1 -1
  89. package/dist/auth/types.js.map +1 -1
  90. package/dist/cli.js +6 -2
  91. package/dist/cli.js.map +1 -1
  92. package/dist/compat/extension-oauth-types.d.ts +4 -0
  93. package/dist/compat/extension-oauth-types.d.ts.map +1 -1
  94. package/dist/compat/extension-oauth-types.js.map +1 -1
  95. package/dist/index.d.ts +4 -3
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +4 -2
  98. package/dist/index.js.map +1 -1
  99. package/dist/models.d.ts +4 -0
  100. package/dist/models.d.ts.map +1 -1
  101. package/dist/models.generated.js +1 -1
  102. package/dist/models.generated.js.map +1 -1
  103. package/dist/models.js +20 -6
  104. package/dist/models.js.map +1 -1
  105. package/dist/providers/amazon-bedrock.models.js +1 -1
  106. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  107. package/dist/providers/ant-ling.models.js +1 -1
  108. package/dist/providers/ant-ling.models.js.map +1 -1
  109. package/dist/providers/anthropic.models.js +1 -1
  110. package/dist/providers/anthropic.models.js.map +1 -1
  111. package/dist/providers/azure.models.js +1 -1
  112. package/dist/providers/azure.models.js.map +1 -1
  113. package/dist/providers/baseten.models.js +1 -1
  114. package/dist/providers/baseten.models.js.map +1 -1
  115. package/dist/providers/cerebras.models.js +1 -1
  116. package/dist/providers/cerebras.models.js.map +1 -1
  117. package/dist/providers/cloudflare-ai-gateway.models.js +1 -1
  118. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  119. package/dist/providers/cloudflare-workers-ai.models.js +1 -1
  120. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  121. package/dist/providers/compat-schema.d.ts +444 -304
  122. package/dist/providers/compat-schema.d.ts.map +1 -1
  123. package/dist/providers/compat-schema.js +155 -109
  124. package/dist/providers/compat-schema.js.map +1 -1
  125. package/dist/providers/data/.manifest.json +1 -1
  126. package/dist/providers/data/amazon-bedrock.json +1 -1
  127. package/dist/providers/data/anthropic.json +1 -1
  128. package/dist/providers/data/azure.json +1 -1
  129. package/dist/providers/data/baseten.json +1 -1
  130. package/dist/providers/data/cerebras.json +1 -1
  131. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  132. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  133. package/dist/providers/data/fireworks.json +1 -1
  134. package/dist/providers/data/github-copilot.json +1 -1
  135. package/dist/providers/data/google-vertex.json +1 -1
  136. package/dist/providers/data/google.json +1 -1
  137. package/dist/providers/data/groq.json +1 -1
  138. package/dist/providers/data/huggingface.json +1 -1
  139. package/dist/providers/data/kimi-coding.json +1 -1
  140. package/dist/providers/data/minimax-cn.json +1 -1
  141. package/dist/providers/data/minimax.json +1 -1
  142. package/dist/providers/data/mistral.json +1 -1
  143. package/dist/providers/data/moonshotai-cn.json +1 -1
  144. package/dist/providers/data/moonshotai.json +1 -1
  145. package/dist/providers/data/nvidia.json +1 -1
  146. package/dist/providers/data/openai-codex.json +1 -1
  147. package/dist/providers/data/openai.json +1 -1
  148. package/dist/providers/data/opencode-go.json +1 -1
  149. package/dist/providers/data/opencode.json +1 -1
  150. package/dist/providers/data/openrouter.json +1 -1
  151. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  152. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  153. package/dist/providers/data/qwen-token-plan.json +1 -1
  154. package/dist/providers/data/radius.json +1 -1
  155. package/dist/providers/data/together.json +1 -1
  156. package/dist/providers/data/typesafe.json +1 -1
  157. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  158. package/dist/providers/data/xai.json +1 -1
  159. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  160. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  161. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  162. package/dist/providers/data/xiaomi.json +1 -1
  163. package/dist/providers/data/zai-coding-cn.json +1 -1
  164. package/dist/providers/data/zai.json +1 -1
  165. package/dist/providers/deepseek.models.js +1 -1
  166. package/dist/providers/deepseek.models.js.map +1 -1
  167. package/dist/providers/faux.d.ts.map +1 -1
  168. package/dist/providers/faux.js +7 -2
  169. package/dist/providers/faux.js.map +1 -1
  170. package/dist/providers/fireworks.models.js +1 -1
  171. package/dist/providers/fireworks.models.js.map +1 -1
  172. package/dist/providers/github-copilot.models.js +1 -1
  173. package/dist/providers/github-copilot.models.js.map +1 -1
  174. package/dist/providers/google-vertex.models.js +1 -1
  175. package/dist/providers/google-vertex.models.js.map +1 -1
  176. package/dist/providers/google.models.js +1 -1
  177. package/dist/providers/google.models.js.map +1 -1
  178. package/dist/providers/groq.models.js +1 -1
  179. package/dist/providers/groq.models.js.map +1 -1
  180. package/dist/providers/huggingface.models.js +1 -1
  181. package/dist/providers/huggingface.models.js.map +1 -1
  182. package/dist/providers/kimi-coding.models.js +1 -1
  183. package/dist/providers/kimi-coding.models.js.map +1 -1
  184. package/dist/providers/meta.models.js +1 -1
  185. package/dist/providers/meta.models.js.map +1 -1
  186. package/dist/providers/minimax-cn.models.js +1 -1
  187. package/dist/providers/minimax-cn.models.js.map +1 -1
  188. package/dist/providers/minimax.models.js +1 -1
  189. package/dist/providers/minimax.models.js.map +1 -1
  190. package/dist/providers/mistral.models.js +1 -1
  191. package/dist/providers/mistral.models.js.map +1 -1
  192. package/dist/providers/model-schema.d.ts +65 -65
  193. package/dist/providers/model-schema.d.ts.map +1 -1
  194. package/dist/providers/model-schema.js +44 -31
  195. package/dist/providers/model-schema.js.map +1 -1
  196. package/dist/providers/moonshotai-cn.models.js +1 -1
  197. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  198. package/dist/providers/moonshotai.models.js +1 -1
  199. package/dist/providers/moonshotai.models.js.map +1 -1
  200. package/dist/providers/nvidia.models.js +1 -1
  201. package/dist/providers/nvidia.models.js.map +1 -1
  202. package/dist/providers/openai-codex.models.js +1 -1
  203. package/dist/providers/openai-codex.models.js.map +1 -1
  204. package/dist/providers/openai.models.js +1 -1
  205. package/dist/providers/openai.models.js.map +1 -1
  206. package/dist/providers/opencode-go.models.js +1 -1
  207. package/dist/providers/opencode-go.models.js.map +1 -1
  208. package/dist/providers/opencode.js +1 -1
  209. package/dist/providers/opencode.js.map +1 -1
  210. package/dist/providers/opencode.models.js +1 -1
  211. package/dist/providers/opencode.models.js.map +1 -1
  212. package/dist/providers/openrouter.models.js +1 -1
  213. package/dist/providers/openrouter.models.js.map +1 -1
  214. package/dist/providers/qwen-token-plan-cn.models.js +1 -1
  215. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  216. package/dist/providers/qwen-token-plan-individual.models.js +1 -1
  217. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
  218. package/dist/providers/qwen-token-plan.models.js +1 -1
  219. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  220. package/dist/providers/radius-config.d.ts.map +1 -1
  221. package/dist/providers/radius-config.js +2 -1
  222. package/dist/providers/radius-config.js.map +1 -1
  223. package/dist/providers/radius.models.js +1 -1
  224. package/dist/providers/radius.models.js.map +1 -1
  225. package/dist/providers/schema-builders.d.ts +10 -0
  226. package/dist/providers/schema-builders.d.ts.map +1 -0
  227. package/dist/providers/schema-builders.js +18 -0
  228. package/dist/providers/schema-builders.js.map +1 -0
  229. package/dist/providers/together.models.js +1 -1
  230. package/dist/providers/together.models.js.map +1 -1
  231. package/dist/providers/typesafe.models.js +1 -1
  232. package/dist/providers/typesafe.models.js.map +1 -1
  233. package/dist/providers/vercel-ai-gateway.models.js +1 -1
  234. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  235. package/dist/providers/xai.models.js +1 -1
  236. package/dist/providers/xai.models.js.map +1 -1
  237. package/dist/providers/xiaomi-token-plan-ams.models.js +1 -1
  238. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  239. package/dist/providers/xiaomi-token-plan-cn.models.js +1 -1
  240. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  241. package/dist/providers/xiaomi-token-plan-sgp.models.js +1 -1
  242. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  243. package/dist/providers/xiaomi.models.js +1 -1
  244. package/dist/providers/xiaomi.models.js.map +1 -1
  245. package/dist/providers/zai-coding-cn.models.js +1 -1
  246. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  247. package/dist/providers/zai.models.js +1 -1
  248. package/dist/providers/zai.models.js.map +1 -1
  249. package/dist/telemetry.d.ts +288 -0
  250. package/dist/telemetry.d.ts.map +1 -0
  251. package/dist/telemetry.js +192 -0
  252. package/dist/telemetry.js.map +1 -0
  253. package/dist/types.d.ts +25 -7
  254. package/dist/types.d.ts.map +1 -1
  255. package/dist/types.js.map +1 -1
  256. package/dist/utils/error-body.d.ts.map +1 -1
  257. package/dist/utils/error-body.js +2 -1
  258. package/dist/utils/error-body.js.map +1 -1
  259. package/dist/utils/identity.d.ts +65 -0
  260. package/dist/utils/identity.d.ts.map +1 -0
  261. package/dist/utils/identity.js +141 -0
  262. package/dist/utils/identity.js.map +1 -0
  263. package/dist/utils/openrouter-cost.d.ts +24 -0
  264. package/dist/utils/openrouter-cost.d.ts.map +1 -0
  265. package/dist/utils/openrouter-cost.js +34 -0
  266. package/dist/utils/openrouter-cost.js.map +1 -0
  267. package/dist/utils/overflow.d.ts +1 -0
  268. package/dist/utils/overflow.d.ts.map +1 -1
  269. package/dist/utils/overflow.js +8 -1
  270. package/dist/utils/overflow.js.map +1 -1
  271. package/dist/utils/retry.d.ts.map +1 -1
  272. package/dist/utils/retry.js +19 -7
  273. package/dist/utils/retry.js.map +1 -1
  274. package/dist/utils/streaming-json.d.ts +84 -0
  275. package/dist/utils/streaming-json.d.ts.map +1 -0
  276. package/dist/utils/streaming-json.js +513 -0
  277. package/dist/utils/streaming-json.js.map +1 -0
  278. package/dist/utils/{typebox-helpers.d.ts → string-enum.d.ts} +5 -5
  279. package/dist/utils/string-enum.d.ts.map +1 -0
  280. package/dist/utils/{typebox-helpers.js → string-enum.js} +5 -6
  281. package/dist/utils/string-enum.js.map +1 -0
  282. package/dist/utils/text.d.ts +7 -0
  283. package/dist/utils/text.d.ts.map +1 -1
  284. package/dist/utils/text.js +9 -0
  285. package/dist/utils/text.js.map +1 -1
  286. package/dist/utils/transcript.d.ts +23 -9
  287. package/dist/utils/transcript.d.ts.map +1 -1
  288. package/dist/utils/transcript.js +30 -19
  289. package/dist/utils/transcript.js.map +1 -1
  290. package/dist/utils/validation.d.ts +5 -3
  291. package/dist/utils/validation.d.ts.map +1 -1
  292. package/dist/utils/validation.js +27 -277
  293. package/dist/utils/validation.js.map +1 -1
  294. package/dist/utils/version.d.ts +2 -0
  295. package/dist/utils/version.d.ts.map +1 -0
  296. package/dist/utils/version.js +3 -0
  297. package/dist/utils/version.js.map +1 -0
  298. package/package.json +11 -10
  299. package/dist/utils/pi-user-agent.d.ts +0 -2
  300. package/dist/utils/pi-user-agent.d.ts.map +0 -1
  301. package/dist/utils/pi-user-agent.js +0 -12
  302. package/dist/utils/pi-user-agent.js.map +0 -1
  303. package/dist/utils/typebox-helpers.d.ts.map +0 -1
  304. package/dist/utils/typebox-helpers.js.map +0 -1
@@ -0,0 +1,288 @@
1
+ import { type TelemetrySpan } from "@earendil-works/pi-telemetry";
2
+ import type { LazyStreamObserver } from "./api/lazy.ts";
3
+ import type { Api, Model } from "./types.ts";
4
+ /** Pi-owned request metadata, bounded error status, events, and low-cardinality metrics. */
5
+ export declare const AI_TELEMETRY_SCHEMA: {
6
+ readonly version: 1;
7
+ readonly spans: {
8
+ readonly "pi.ai.request": {
9
+ readonly description: "One logical model request, including authentication and provider setup.";
10
+ readonly parents: {
11
+ readonly kind: "any";
12
+ };
13
+ readonly startAttributes: {
14
+ readonly provider: {
15
+ readonly type: "string";
16
+ readonly description: "Provider identifier.";
17
+ readonly required: true;
18
+ };
19
+ readonly api: {
20
+ readonly type: "string";
21
+ readonly description: "API identifier.";
22
+ readonly required: true;
23
+ };
24
+ readonly model: {
25
+ readonly type: "string";
26
+ readonly description: "Requested model identifier.";
27
+ readonly required: true;
28
+ };
29
+ readonly reasoning: {
30
+ readonly type: "string";
31
+ readonly description: "Scalar requested reasoning level.";
32
+ readonly required: false;
33
+ };
34
+ };
35
+ readonly endAttributes: {
36
+ readonly stop: {
37
+ readonly type: "string";
38
+ readonly description: "Normalized stop reason.";
39
+ readonly values: readonly ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"];
40
+ };
41
+ readonly "usage.input": {
42
+ readonly type: "number";
43
+ readonly description: "Uncached input tokens.";
44
+ };
45
+ readonly "usage.output": {
46
+ readonly type: "number";
47
+ readonly description: "Output tokens.";
48
+ };
49
+ readonly "usage.cache_read": {
50
+ readonly type: "number";
51
+ readonly description: "Cache-read tokens.";
52
+ };
53
+ readonly "usage.cache_write": {
54
+ readonly type: "number";
55
+ readonly description: "Cache-write tokens.";
56
+ };
57
+ readonly "cost.total": {
58
+ readonly type: "number";
59
+ readonly description: "Total request cost in USD.";
60
+ };
61
+ readonly "response.id": {
62
+ readonly type: "string";
63
+ readonly description: "Provider response identifier.";
64
+ readonly cardinality: "high";
65
+ };
66
+ };
67
+ readonly events: {
68
+ readonly "pi.ai.first_chunk": {
69
+ readonly description: "First normalized stream event delivered.";
70
+ readonly attributes: {};
71
+ };
72
+ readonly "pi.ai.block": {
73
+ readonly description: "A completed content block; content is never recorded.";
74
+ readonly attributes: {
75
+ readonly type: {
76
+ readonly type: "string";
77
+ readonly description: "Block kind.";
78
+ readonly values: readonly ["text", "thinking", "tool_call"];
79
+ readonly required: true;
80
+ };
81
+ readonly index: {
82
+ readonly type: "number";
83
+ readonly description: "Content block index.";
84
+ readonly required: true;
85
+ };
86
+ readonly chars: {
87
+ readonly type: "number";
88
+ readonly description: "UTF-16 character count.";
89
+ readonly required: true;
90
+ };
91
+ readonly tool: {
92
+ readonly type: "string";
93
+ readonly description: "Tool name, for tool-call blocks only.";
94
+ readonly required: false;
95
+ };
96
+ };
97
+ };
98
+ };
99
+ readonly status: {
100
+ readonly default: "ok";
101
+ readonly errorWhen: "Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok.";
102
+ };
103
+ };
104
+ readonly "pi.ai.poll": {
105
+ readonly parents: {
106
+ readonly kind: "any";
107
+ };
108
+ readonly startAttributes: {
109
+ readonly provider: {
110
+ readonly type: "string";
111
+ readonly description: "Provider identifier.";
112
+ readonly required: true;
113
+ };
114
+ readonly api: {
115
+ readonly type: "string";
116
+ readonly description: "API identifier.";
117
+ readonly required: true;
118
+ };
119
+ readonly model: {
120
+ readonly type: "string";
121
+ readonly description: "Requested model identifier.";
122
+ readonly required: true;
123
+ };
124
+ readonly reasoning: {
125
+ readonly type: "string";
126
+ readonly description: "Scalar requested reasoning level.";
127
+ readonly required: false;
128
+ };
129
+ };
130
+ readonly endAttributes: {
131
+ readonly stop: {
132
+ readonly type: "string";
133
+ readonly description: "Normalized stop reason.";
134
+ readonly values: readonly ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"];
135
+ };
136
+ readonly "usage.input": {
137
+ readonly type: "number";
138
+ readonly description: "Uncached input tokens.";
139
+ };
140
+ readonly "usage.output": {
141
+ readonly type: "number";
142
+ readonly description: "Output tokens.";
143
+ };
144
+ readonly "usage.cache_read": {
145
+ readonly type: "number";
146
+ readonly description: "Cache-read tokens.";
147
+ };
148
+ readonly "usage.cache_write": {
149
+ readonly type: "number";
150
+ readonly description: "Cache-write tokens.";
151
+ };
152
+ readonly "cost.total": {
153
+ readonly type: "number";
154
+ readonly description: "Total request cost in USD.";
155
+ };
156
+ readonly "response.id": {
157
+ readonly type: "string";
158
+ readonly description: "Provider response identifier.";
159
+ readonly cardinality: "high";
160
+ };
161
+ };
162
+ readonly events: {
163
+ readonly "pi.ai.first_chunk": {
164
+ readonly description: "First normalized stream event delivered.";
165
+ readonly attributes: {};
166
+ };
167
+ readonly "pi.ai.block": {
168
+ readonly description: "A completed content block; content is never recorded.";
169
+ readonly attributes: {
170
+ readonly type: {
171
+ readonly type: "string";
172
+ readonly description: "Block kind.";
173
+ readonly values: readonly ["text", "thinking", "tool_call"];
174
+ readonly required: true;
175
+ };
176
+ readonly index: {
177
+ readonly type: "number";
178
+ readonly description: "Content block index.";
179
+ readonly required: true;
180
+ };
181
+ readonly chars: {
182
+ readonly type: "number";
183
+ readonly description: "UTF-16 character count.";
184
+ readonly required: true;
185
+ };
186
+ readonly tool: {
187
+ readonly type: "string";
188
+ readonly description: "Tool name, for tool-call blocks only.";
189
+ readonly required: false;
190
+ };
191
+ };
192
+ };
193
+ };
194
+ readonly status: {
195
+ readonly default: "ok";
196
+ readonly errorWhen: "Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok.";
197
+ };
198
+ readonly description: "One deferred-response poll, not the deferred request's lifetime.";
199
+ };
200
+ };
201
+ readonly metrics: {
202
+ readonly "pi.ai.request.duration": {
203
+ readonly kind: "histogram";
204
+ readonly description: "Logical request or poll duration.";
205
+ readonly unit: "ms";
206
+ readonly attributes: {
207
+ readonly provider: {
208
+ readonly type: "string";
209
+ readonly description: "Provider identifier.";
210
+ readonly required: true;
211
+ };
212
+ readonly model: {
213
+ readonly type: "string";
214
+ readonly description: "Requested model identifier.";
215
+ readonly required: true;
216
+ };
217
+ readonly stop: {
218
+ readonly type: "string";
219
+ readonly description: "Normalized stop reason.";
220
+ readonly values: readonly ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"];
221
+ readonly required: true;
222
+ };
223
+ };
224
+ };
225
+ readonly "pi.ai.first_chunk.duration": {
226
+ readonly kind: "histogram";
227
+ readonly description: "Time to the first normalized stream event.";
228
+ readonly unit: "ms";
229
+ readonly attributes: {
230
+ readonly provider: {
231
+ readonly type: "string";
232
+ readonly description: "Provider identifier.";
233
+ readonly required: true;
234
+ };
235
+ readonly model: {
236
+ readonly type: "string";
237
+ readonly description: "Requested model identifier.";
238
+ readonly required: true;
239
+ };
240
+ };
241
+ };
242
+ readonly "pi.ai.tokens": {
243
+ readonly kind: "counter";
244
+ readonly description: "Reported model token usage; pending and deferred polls are excluded.";
245
+ readonly unit: "token";
246
+ readonly attributes: {
247
+ readonly provider: {
248
+ readonly type: "string";
249
+ readonly description: "Provider identifier.";
250
+ readonly required: true;
251
+ };
252
+ readonly model: {
253
+ readonly type: "string";
254
+ readonly description: "Requested model identifier.";
255
+ readonly required: true;
256
+ };
257
+ readonly kind: {
258
+ readonly type: "string";
259
+ readonly description: "Token usage category.";
260
+ readonly values: readonly ["input", "output", "cache_read", "cache_write"];
261
+ readonly required: true;
262
+ };
263
+ };
264
+ };
265
+ readonly "pi.ai.cost": {
266
+ readonly kind: "counter";
267
+ readonly description: "Reported model cost; pending and deferred polls are excluded.";
268
+ readonly unit: "USD";
269
+ readonly attributes: {
270
+ readonly provider: {
271
+ readonly type: "string";
272
+ readonly description: "Provider identifier.";
273
+ readonly required: true;
274
+ };
275
+ readonly model: {
276
+ readonly type: "string";
277
+ readonly description: "Requested model identifier.";
278
+ readonly required: true;
279
+ };
280
+ };
281
+ };
282
+ };
283
+ };
284
+ export declare function observeModelRequest(requestedModel: Model<Api>, options: {
285
+ telemetry?: TelemetrySpan;
286
+ reasoning?: unknown;
287
+ } | undefined, poll: boolean): LazyStreamObserver;
288
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ import { createTypedMetrics, createTypedSpanStarter, defineTelemetrySchema, NOOP_TELEMETRY_CONTEXT, NOOP_TELEMETRY_METRICS, } from "@earendil-works/pi-telemetry";
2
+ import { ownedSlice } from "./utils/text.js";
3
+ const provider = { type: "string", description: "Provider identifier.", required: true };
4
+ const model = { type: "string", description: "Requested model identifier.", required: true };
5
+ const stop = {
6
+ type: "string",
7
+ description: "Normalized stop reason.",
8
+ values: ["pending", "stop", "length", "toolUse", "error", "aborted", "deferred"],
9
+ };
10
+ const request = {
11
+ description: "One logical model request, including authentication and provider setup.",
12
+ parents: { kind: "any" },
13
+ startAttributes: {
14
+ provider,
15
+ api: { type: "string", description: "API identifier.", required: true },
16
+ model,
17
+ reasoning: { type: "string", description: "Scalar requested reasoning level.", required: false },
18
+ },
19
+ endAttributes: {
20
+ stop,
21
+ "usage.input": { type: "number", description: "Uncached input tokens." },
22
+ "usage.output": { type: "number", description: "Output tokens." },
23
+ "usage.cache_read": { type: "number", description: "Cache-read tokens." },
24
+ "usage.cache_write": { type: "number", description: "Cache-write tokens." },
25
+ "cost.total": { type: "number", description: "Total request cost in USD." },
26
+ "response.id": { type: "string", description: "Provider response identifier.", cardinality: "high" },
27
+ },
28
+ events: {
29
+ "pi.ai.first_chunk": { description: "First normalized stream event delivered.", attributes: {} },
30
+ "pi.ai.block": {
31
+ description: "A completed content block; content is never recorded.",
32
+ attributes: {
33
+ type: {
34
+ type: "string",
35
+ description: "Block kind.",
36
+ values: ["text", "thinking", "tool_call"],
37
+ required: true,
38
+ },
39
+ index: { type: "number", description: "Content block index.", required: true },
40
+ chars: { type: "number", description: "UTF-16 character count.", required: true },
41
+ tool: { type: "string", description: "Tool name, for tool-call blocks only.", required: false },
42
+ },
43
+ },
44
+ },
45
+ status: {
46
+ default: "ok",
47
+ errorWhen: "Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok.",
48
+ },
49
+ };
50
+ /** Pi-owned request metadata, bounded error status, events, and low-cardinality metrics. */
51
+ export const AI_TELEMETRY_SCHEMA = defineTelemetrySchema({
52
+ version: 1,
53
+ spans: {
54
+ "pi.ai.request": request,
55
+ "pi.ai.poll": { ...request, description: "One deferred-response poll, not the deferred request's lifetime." },
56
+ },
57
+ metrics: {
58
+ "pi.ai.request.duration": {
59
+ kind: "histogram",
60
+ description: "Logical request or poll duration.",
61
+ unit: "ms",
62
+ attributes: { provider, model, stop: { ...stop, required: true } },
63
+ },
64
+ "pi.ai.first_chunk.duration": {
65
+ kind: "histogram",
66
+ description: "Time to the first normalized stream event.",
67
+ unit: "ms",
68
+ attributes: { provider, model },
69
+ },
70
+ "pi.ai.tokens": {
71
+ kind: "counter",
72
+ description: "Reported model token usage; pending and deferred polls are excluded.",
73
+ unit: "token",
74
+ attributes: {
75
+ provider,
76
+ model,
77
+ kind: {
78
+ type: "string",
79
+ description: "Token usage category.",
80
+ values: ["input", "output", "cache_read", "cache_write"],
81
+ required: true,
82
+ },
83
+ },
84
+ },
85
+ "pi.ai.cost": {
86
+ kind: "counter",
87
+ description: "Reported model cost; pending and deferred polls are excluded.",
88
+ unit: "USD",
89
+ attributes: { provider, model },
90
+ },
91
+ },
92
+ });
93
+ function createInstruments(adapter) {
94
+ const metrics = createTypedMetrics(adapter, [AI_TELEMETRY_SCHEMA]);
95
+ return {
96
+ requestDuration: metrics.histogram("pi.ai.request.duration"),
97
+ firstChunkDuration: metrics.histogram("pi.ai.first_chunk.duration"),
98
+ tokens: metrics.counter("pi.ai.tokens"),
99
+ cost: metrics.counter("pi.ai.cost"),
100
+ };
101
+ }
102
+ const instrumentCache = new WeakMap();
103
+ export function observeModelRequest(requestedModel, options, poll) {
104
+ const started = performance.now();
105
+ const attributes = { provider: requestedModel.provider, model: requestedModel.id };
106
+ const adapter = options?.telemetry?.metrics ?? NOOP_TELEMETRY_METRICS;
107
+ let instruments = instrumentCache.get(adapter);
108
+ if (!instruments) {
109
+ instruments = createInstruments(adapter);
110
+ instrumentCache.set(adapter, instruments);
111
+ }
112
+ const { requestDuration, firstChunkDuration, tokens, cost } = instruments;
113
+ let span;
114
+ let finish;
115
+ let first = true;
116
+ const toolChars = new Map();
117
+ const finished = new Promise((resolve) => {
118
+ finish = resolve;
119
+ });
120
+ const run = (activeSpan) => {
121
+ span = activeSpan;
122
+ return finished;
123
+ };
124
+ const startAttributes = {
125
+ ...attributes,
126
+ api: requestedModel.api,
127
+ ...(typeof options?.reasoning === "string" ? { reasoning: options.reasoning } : {}),
128
+ };
129
+ const start = createTypedSpanStarter(options?.telemetry ?? NOOP_TELEMETRY_CONTEXT, [AI_TELEMETRY_SCHEMA]);
130
+ if (poll)
131
+ void start("pi.ai.poll", startAttributes, run);
132
+ else
133
+ void start("pi.ai.request", startAttributes, run);
134
+ return {
135
+ onEvent(event) {
136
+ if (first) {
137
+ first = false;
138
+ span.addEvent("pi.ai.first_chunk");
139
+ firstChunkDuration.record(performance.now() - started, attributes, span);
140
+ }
141
+ if (event.type === "toolcall_delta") {
142
+ toolChars.set(event.contentIndex, (toolChars.get(event.contentIndex) ?? 0) + event.delta.length);
143
+ }
144
+ else if (event.type === "text_end" || event.type === "thinking_end") {
145
+ span.addEvent("pi.ai.block", {
146
+ type: event.type === "text_end" ? "text" : "thinking",
147
+ index: event.contentIndex,
148
+ chars: event.content.length,
149
+ });
150
+ }
151
+ else if (event.type === "toolcall_end") {
152
+ const chars = toolChars.get(event.contentIndex) ?? 0;
153
+ toolChars.delete(event.contentIndex);
154
+ span.addEvent("pi.ai.block", {
155
+ type: "tool_call",
156
+ index: event.contentIndex,
157
+ chars,
158
+ tool: event.toolCall.name,
159
+ });
160
+ }
161
+ },
162
+ onResult(message) {
163
+ if (message) {
164
+ span.setAttributes({
165
+ stop: message.stopReason,
166
+ "usage.input": message.usage.input,
167
+ "usage.output": message.usage.output,
168
+ "usage.cache_read": message.usage.cacheRead,
169
+ "usage.cache_write": message.usage.cacheWrite,
170
+ "cost.total": message.usage.cost.total,
171
+ "response.id": message.responseId,
172
+ });
173
+ if (message.stopReason === "error") {
174
+ span.setStatus({
175
+ status: "error",
176
+ error: { name: "provider_error", message: ownedSlice(message.errorMessage ?? "", 0, 500) },
177
+ });
178
+ }
179
+ requestDuration.record(performance.now() - started, { ...attributes, stop: message.stopReason }, span);
180
+ if (!poll || (message.stopReason !== "pending" && message.stopReason !== "deferred")) {
181
+ tokens.add(message.usage.input, { ...attributes, kind: "input" });
182
+ tokens.add(message.usage.output, { ...attributes, kind: "output" });
183
+ tokens.add(message.usage.cacheRead, { ...attributes, kind: "cache_read" });
184
+ tokens.add(message.usage.cacheWrite, { ...attributes, kind: "cache_write" });
185
+ cost.add(message.usage.cost.total, attributes);
186
+ }
187
+ }
188
+ finish();
189
+ },
190
+ };
191
+ }
192
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tcreateTypedMetrics,\n\tcreateTypedSpanStarter,\n\tdefineTelemetrySchema,\n\tNOOP_TELEMETRY_CONTEXT,\n\tNOOP_TELEMETRY_METRICS,\n\ttype SchemaTelemetrySpan,\n\ttype TelemetryMetrics,\n\ttype TelemetrySpan,\n} from \"@earendil-works/pi-telemetry\";\nimport type { LazyStreamObserver } from \"./api/lazy.ts\";\nimport type { Api, Model } from \"./types.ts\";\nimport { ownedSlice } from \"./utils/text.ts\";\n\nconst provider = { type: \"string\", description: \"Provider identifier.\", required: true } as const;\nconst model = { type: \"string\", description: \"Requested model identifier.\", required: true } as const;\nconst stop = {\n\ttype: \"string\",\n\tdescription: \"Normalized stop reason.\",\n\tvalues: [\"pending\", \"stop\", \"length\", \"toolUse\", \"error\", \"aborted\", \"deferred\"],\n} as const;\nconst request = {\n\tdescription: \"One logical model request, including authentication and provider setup.\",\n\tparents: { kind: \"any\" },\n\tstartAttributes: {\n\t\tprovider,\n\t\tapi: { type: \"string\", description: \"API identifier.\", required: true },\n\t\tmodel,\n\t\treasoning: { type: \"string\", description: \"Scalar requested reasoning level.\", required: false },\n\t},\n\tendAttributes: {\n\t\tstop,\n\t\t\"usage.input\": { type: \"number\", description: \"Uncached input tokens.\" },\n\t\t\"usage.output\": { type: \"number\", description: \"Output tokens.\" },\n\t\t\"usage.cache_read\": { type: \"number\", description: \"Cache-read tokens.\" },\n\t\t\"usage.cache_write\": { type: \"number\", description: \"Cache-write tokens.\" },\n\t\t\"cost.total\": { type: \"number\", description: \"Total request cost in USD.\" },\n\t\t\"response.id\": { type: \"string\", description: \"Provider response identifier.\", cardinality: \"high\" },\n\t},\n\tevents: {\n\t\t\"pi.ai.first_chunk\": { description: \"First normalized stream event delivered.\", attributes: {} },\n\t\t\"pi.ai.block\": {\n\t\t\tdescription: \"A completed content block; content is never recorded.\",\n\t\t\tattributes: {\n\t\t\t\ttype: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Block kind.\",\n\t\t\t\t\tvalues: [\"text\", \"thinking\", \"tool_call\"],\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t\tindex: { type: \"number\", description: \"Content block index.\", required: true },\n\t\t\t\tchars: { type: \"number\", description: \"UTF-16 character count.\", required: true },\n\t\t\t\ttool: { type: \"string\", description: \"Tool name, for tool-call blocks only.\", required: false },\n\t\t\t},\n\t\t},\n\t},\n\tstatus: {\n\t\tdefault: \"ok\",\n\t\terrorWhen: \"Stop reason is error: provider_error with at most 500 error-message characters. Aborted stays ok.\",\n\t},\n} as const;\n\n/** Pi-owned request metadata, bounded error status, events, and low-cardinality metrics. */\nexport const AI_TELEMETRY_SCHEMA = defineTelemetrySchema({\n\tversion: 1,\n\tspans: {\n\t\t\"pi.ai.request\": request,\n\t\t\"pi.ai.poll\": { ...request, description: \"One deferred-response poll, not the deferred request's lifetime.\" },\n\t},\n\tmetrics: {\n\t\t\"pi.ai.request.duration\": {\n\t\t\tkind: \"histogram\",\n\t\t\tdescription: \"Logical request or poll duration.\",\n\t\t\tunit: \"ms\",\n\t\t\tattributes: { provider, model, stop: { ...stop, required: true } },\n\t\t},\n\t\t\"pi.ai.first_chunk.duration\": {\n\t\t\tkind: \"histogram\",\n\t\t\tdescription: \"Time to the first normalized stream event.\",\n\t\t\tunit: \"ms\",\n\t\t\tattributes: { provider, model },\n\t\t},\n\t\t\"pi.ai.tokens\": {\n\t\t\tkind: \"counter\",\n\t\t\tdescription: \"Reported model token usage; pending and deferred polls are excluded.\",\n\t\t\tunit: \"token\",\n\t\t\tattributes: {\n\t\t\t\tprovider,\n\t\t\t\tmodel,\n\t\t\t\tkind: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tdescription: \"Token usage category.\",\n\t\t\t\t\tvalues: [\"input\", \"output\", \"cache_read\", \"cache_write\"],\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"pi.ai.cost\": {\n\t\t\tkind: \"counter\",\n\t\t\tdescription: \"Reported model cost; pending and deferred polls are excluded.\",\n\t\t\tunit: \"USD\",\n\t\t\tattributes: { provider, model },\n\t\t},\n\t},\n});\n\ntype RequestSpan = SchemaTelemetrySpan<typeof AI_TELEMETRY_SCHEMA, \"pi.ai.request\">;\n\nfunction createInstruments(adapter: TelemetryMetrics) {\n\tconst metrics = createTypedMetrics(adapter, [AI_TELEMETRY_SCHEMA]);\n\treturn {\n\t\trequestDuration: metrics.histogram(\"pi.ai.request.duration\"),\n\t\tfirstChunkDuration: metrics.histogram(\"pi.ai.first_chunk.duration\"),\n\t\ttokens: metrics.counter(\"pi.ai.tokens\"),\n\t\tcost: metrics.counter(\"pi.ai.cost\"),\n\t};\n}\n\nconst instrumentCache = new WeakMap<TelemetryMetrics, ReturnType<typeof createInstruments>>();\n\nexport function observeModelRequest(\n\trequestedModel: Model<Api>,\n\toptions: { telemetry?: TelemetrySpan; reasoning?: unknown } | undefined,\n\tpoll: boolean,\n): LazyStreamObserver {\n\tconst started = performance.now();\n\tconst attributes = { provider: requestedModel.provider, model: requestedModel.id };\n\tconst adapter = options?.telemetry?.metrics ?? NOOP_TELEMETRY_METRICS;\n\tlet instruments = instrumentCache.get(adapter);\n\tif (!instruments) {\n\t\tinstruments = createInstruments(adapter);\n\t\tinstrumentCache.set(adapter, instruments);\n\t}\n\tconst { requestDuration, firstChunkDuration, tokens, cost } = instruments;\n\tlet span!: RequestSpan;\n\tlet finish!: () => void;\n\tlet first = true;\n\tconst toolChars = new Map<number, number>();\n\tconst finished = new Promise<void>((resolve) => {\n\t\tfinish = resolve;\n\t});\n\tconst run = (activeSpan: RequestSpan): Promise<void> => {\n\t\tspan = activeSpan;\n\t\treturn finished;\n\t};\n\tconst startAttributes = {\n\t\t...attributes,\n\t\tapi: requestedModel.api,\n\t\t...(typeof options?.reasoning === \"string\" ? { reasoning: options.reasoning } : {}),\n\t};\n\tconst start = createTypedSpanStarter(options?.telemetry ?? NOOP_TELEMETRY_CONTEXT, [AI_TELEMETRY_SCHEMA]);\n\tif (poll) void start(\"pi.ai.poll\", startAttributes, run);\n\telse void start(\"pi.ai.request\", startAttributes, run);\n\n\treturn {\n\t\tonEvent(event) {\n\t\t\tif (first) {\n\t\t\t\tfirst = false;\n\t\t\t\tspan.addEvent(\"pi.ai.first_chunk\");\n\t\t\t\tfirstChunkDuration.record(performance.now() - started, attributes, span);\n\t\t\t}\n\t\t\tif (event.type === \"toolcall_delta\") {\n\t\t\t\ttoolChars.set(event.contentIndex, (toolChars.get(event.contentIndex) ?? 0) + event.delta.length);\n\t\t\t} else if (event.type === \"text_end\" || event.type === \"thinking_end\") {\n\t\t\t\tspan.addEvent(\"pi.ai.block\", {\n\t\t\t\t\ttype: event.type === \"text_end\" ? \"text\" : \"thinking\",\n\t\t\t\t\tindex: event.contentIndex,\n\t\t\t\t\tchars: event.content.length,\n\t\t\t\t});\n\t\t\t} else if (event.type === \"toolcall_end\") {\n\t\t\t\tconst chars = toolChars.get(event.contentIndex) ?? 0;\n\t\t\t\ttoolChars.delete(event.contentIndex);\n\t\t\t\tspan.addEvent(\"pi.ai.block\", {\n\t\t\t\t\ttype: \"tool_call\",\n\t\t\t\t\tindex: event.contentIndex,\n\t\t\t\t\tchars,\n\t\t\t\t\ttool: event.toolCall.name,\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\tonResult(message) {\n\t\t\tif (message) {\n\t\t\t\tspan.setAttributes({\n\t\t\t\t\tstop: message.stopReason,\n\t\t\t\t\t\"usage.input\": message.usage.input,\n\t\t\t\t\t\"usage.output\": message.usage.output,\n\t\t\t\t\t\"usage.cache_read\": message.usage.cacheRead,\n\t\t\t\t\t\"usage.cache_write\": message.usage.cacheWrite,\n\t\t\t\t\t\"cost.total\": message.usage.cost.total,\n\t\t\t\t\t\"response.id\": message.responseId,\n\t\t\t\t});\n\t\t\t\tif (message.stopReason === \"error\") {\n\t\t\t\t\tspan.setStatus({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: { name: \"provider_error\", message: ownedSlice(message.errorMessage ?? \"\", 0, 500) },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\trequestDuration.record(performance.now() - started, { ...attributes, stop: message.stopReason }, span);\n\t\t\t\tif (!poll || (message.stopReason !== \"pending\" && message.stopReason !== \"deferred\")) {\n\t\t\t\t\ttokens.add(message.usage.input, { ...attributes, kind: \"input\" });\n\t\t\t\t\ttokens.add(message.usage.output, { ...attributes, kind: \"output\" });\n\t\t\t\t\ttokens.add(message.usage.cacheRead, { ...attributes, kind: \"cache_read\" });\n\t\t\t\t\ttokens.add(message.usage.cacheWrite, { ...attributes, kind: \"cache_write\" });\n\t\t\t\t\tcost.add(message.usage.cost.total, attributes);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinish();\n\t\t},\n\t};\n}\n"]}
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TelemetryContext } from "@earendil-works/pi-telemetry";
1
+ import type { TelemetrySpan } from "@earendil-works/pi-telemetry";
2
2
  import type { AnthropicOptions } from "./api/anthropic-messages.ts";
3
3
  import type { AzureOpenAIResponsesOptions } from "./api/azure-openai-responses.ts";
4
4
  import type { BedrockOptions } from "./api/bedrock-converse-stream.ts";
@@ -9,11 +9,12 @@ import type { OpenAICodexResponsesOptions } from "./api/openai-codex-responses.t
9
9
  import type { OpenAICompletionsOptions } from "./api/openai-completions.ts";
10
10
  import type { OpenAIResponsesOptions } from "./api/openai-responses.ts";
11
11
  import type { PiMessagesOptions } from "./api/pi-messages.ts";
12
- import type { AnthropicMessagesCompat, BedrockCompat, MistralConversationsCompat, OpenAICompletionsCompat, OpenAIResponsesCompat } from "./providers/compat-schema.ts";
12
+ import type { AnthropicMessagesCompat, BedrockCompat, MistralConversationsCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, SystemOneCompat } from "./providers/compat-schema.ts";
13
13
  import type { CacheRetention, ModelCost, ModelInputLimits, ModelInputModality, ModelPromptCache, ModelThinkingLevel, ThinkingLevel, ThinkingLevelMap } from "./providers/model-schema.ts";
14
14
  import type { AssistantMessageDiagnostic } from "./utils/diagnostics.ts";
15
15
  import type { AssistantMessageEventStream } from "./utils/event-stream.ts";
16
- export type { AnthropicAllowedFallbackModel, AnthropicMessagesCompat, BedrockCompat, ChatTemplateKwargValue, MistralConversationsCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, OpenRouterRouting, SessionAffinityFormat, ThinkingTokenBudgetField, VercelGatewayRouting, } from "./providers/compat-schema.ts";
16
+ import type { ClientIdentity } from "./utils/identity.ts";
17
+ export type { AnthropicAllowedFallbackModel, AnthropicMessagesCompat, BedrockCompat, ChatTemplateKwargValue, MistralConversationsCompat, OpenAICompletionsCompat, OpenAIResponsesCompat, OpenRouterRouting, SessionAffinityFormat, SystemOneCompat, ThinkingTokenBudgetField, VercelGatewayRouting, } from "./providers/compat-schema.ts";
17
18
  export type { CacheRetention, ModelCost, ModelCostRates, ModelCostTier, ModelImageInputLimits, ModelImageResizeOptions, ModelInputLimits, ModelInputModality, ModelPromptCache, ModelThinkingLevel, ThinkingLevel, ThinkingLevelMap, } from "./providers/model-schema.ts";
18
19
  export type { AssistantMessageEventStream } from "./utils/event-stream.ts";
19
20
  export type KnownApi = "openai-completions" | "mistral-conversations" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-vertex" | "pi-messages";
@@ -46,8 +47,8 @@ export interface ProviderResponse {
46
47
  /** Authentication, HTTP transport, and lifecycle callbacks shared by provider requests. */
47
48
  export interface ProviderRequestOptions<TModel = Model<Api>> {
48
49
  signal?: AbortSignal;
49
- /** Explicit parent context for telemetry produced by this logical request. */
50
- telemetryContext?: TelemetryContext;
50
+ /** Explicit parent span for telemetry produced by this logical request. */
51
+ telemetry?: TelemetrySpan;
51
52
  apiKey?: string;
52
53
  /**
53
54
  * Optional fetch implementation for provider HTTP requests.
@@ -79,6 +80,11 @@ export interface ProviderRequestOptions<TModel = Model<Api>> {
79
80
  * A null value suppresses a provider/API default header with the same name.
80
81
  */
81
82
  headers?: ProviderHeaders;
83
+ /**
84
+ * How the request identifies the calling app: `User-Agent` and provider attribution headers.
85
+ * Absent fields use pi-ai's defaults: a detailed `User-Agent` and no attribution.
86
+ */
87
+ identity?: ClientIdentity;
82
88
  /**
83
89
  * HTTP request timeout in milliseconds for providers/SDKs that support it.
84
90
  * For example, OpenAI and Anthropic SDK clients default to 10 minutes.
@@ -291,11 +297,18 @@ export interface Usage {
291
297
  reasoning?: number;
292
298
  totalTokens: number;
293
299
  cost: {
300
+ /** Catalog-derived input cost. */
294
301
  input: number;
302
+ /** Catalog-derived output cost. */
295
303
  output: number;
304
+ /** Catalog-derived cache-read cost. */
296
305
  cacheRead: number;
306
+ /** Catalog-derived cache-write cost. */
297
307
  cacheWrite: number;
308
+ /** Best available total: provider-reported billed cost when supported, otherwise the catalog estimate. */
298
309
  total: number;
310
+ /** True when `total` is the billed cost reported by the provider. False when it is a catalog estimate; absent also means false. */
311
+ totalFromProvider?: boolean;
299
312
  };
300
313
  }
301
314
  export type StopReason = "pending" | "stop" | "length" | "toolUse" | "error" | "aborted" | "deferred";
@@ -501,7 +514,6 @@ export interface ClassifierResult {
501
514
  errorMessage?: string;
502
515
  timestamp: number;
503
516
  }
504
- import type { TSchema } from "typebox";
505
517
  /** OpenAI grammar variants for constrained sampling. */
506
518
  export type GrammarFormat = "openai_lark" | "openai_regex";
507
519
  export type GrammarVariants = Partial<Record<GrammarFormat, string>>;
@@ -519,7 +531,11 @@ export type ConstrainedSamplingConfig = {
519
531
  type: "grammar";
520
532
  variants: GrammarVariants;
521
533
  };
522
- export interface Tool<TParameters extends TSchema = TSchema> {
534
+ /**
535
+ * A tool the model may call. `parameters` is the JSON Schema of its arguments: pi-schema's builders (which also type
536
+ * the arguments, see `Static` in `@earendil-works/pi-schema`), TypeBox schemas, or any JSON Schema object.
537
+ */
538
+ export interface Tool<TParameters extends object = object> {
523
539
  name: string;
524
540
  description: string;
525
541
  parameters: TParameters;
@@ -668,6 +684,8 @@ export interface ImageModel<TApi extends ImageApi> extends BaseModel<TApi> {
668
684
  export interface ClassifierModel<TApi extends ClassifierApi> extends BaseModel<TApi> {
669
685
  type: "classifier";
670
686
  contextWindow: number;
687
+ /** Compatibility overrides for System One APIs. If not set, auto-detected from provider, baseUrl, and id. */
688
+ compat?: TApi extends "typesafe-system-one" | "cloudflare-workers-ai-system-one" ? SystemOneCompat : never;
671
689
  }
672
690
  /** Model shape for each model type. */
673
691
  export interface ModelTypeMap {