@shpitdev/convex-cliproxy-observability 0.3.6 → 0.3.8

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 (54) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -2
  3. package/dist/capture/content-health.d.ts +4 -1
  4. package/dist/capture/content-health.d.ts.map +1 -1
  5. package/dist/capture/content-health.js +6 -5
  6. package/dist/capture/content-health.js.map +1 -1
  7. package/dist/capture/index.d.ts +21 -0
  8. package/dist/capture/index.d.ts.map +1 -1
  9. package/dist/capture/index.js +53 -0
  10. package/dist/capture/index.js.map +1 -1
  11. package/dist/component/_generated/api.d.ts.map +1 -1
  12. package/dist/component/_generated/api.js.map +1 -1
  13. package/dist/component/_generated/component.d.ts.map +1 -1
  14. package/dist/component/ingest.d.ts +1 -0
  15. package/dist/component/ingest.d.ts.map +1 -1
  16. package/dist/projection.d.ts +6 -3
  17. package/dist/projection.d.ts.map +1 -1
  18. package/dist/projection.js +55 -7
  19. package/dist/projection.js.map +1 -1
  20. package/dist/protocols/anthropic-messages.d.ts +5 -0
  21. package/dist/protocols/anthropic-messages.d.ts.map +1 -1
  22. package/dist/protocols/anthropic-messages.js +38 -4
  23. package/dist/protocols/anthropic-messages.js.map +1 -1
  24. package/dist/protocols/body-parts.d.ts +19 -0
  25. package/dist/protocols/body-parts.d.ts.map +1 -0
  26. package/dist/protocols/body-parts.js +56 -0
  27. package/dist/protocols/body-parts.js.map +1 -0
  28. package/dist/protocols/chat-completions.d.ts.map +1 -1
  29. package/dist/protocols/chat-completions.js +16 -4
  30. package/dist/protocols/chat-completions.js.map +1 -1
  31. package/dist/protocols/checkpoint.d.ts +17 -1
  32. package/dist/protocols/checkpoint.d.ts.map +1 -1
  33. package/dist/protocols/checkpoint.js +59 -15
  34. package/dist/protocols/checkpoint.js.map +1 -1
  35. package/dist/protocols/index.d.ts +2 -1
  36. package/dist/protocols/index.d.ts.map +1 -1
  37. package/dist/protocols/index.js +6 -1
  38. package/dist/protocols/index.js.map +1 -1
  39. package/dist/protocols/responses.d.ts +8 -0
  40. package/dist/protocols/responses.d.ts.map +1 -1
  41. package/dist/protocols/responses.js +43 -1
  42. package/dist/protocols/responses.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/capture/content-health.ts +8 -5
  45. package/src/capture/index.ts +74 -0
  46. package/src/component/_generated/api.ts +5 -6
  47. package/src/component/_generated/component.ts +6 -6
  48. package/src/projection.ts +71 -16
  49. package/src/protocols/anthropic-messages.ts +39 -8
  50. package/src/protocols/body-parts.ts +58 -0
  51. package/src/protocols/chat-completions.ts +13 -4
  52. package/src/protocols/checkpoint.ts +64 -14
  53. package/src/protocols/index.ts +8 -1
  54. package/src/protocols/responses.ts +50 -1
@@ -1,10 +1,43 @@
1
1
  import type { RecordValue } from "./types.js";
2
2
  import { append, count, list, object } from "./values.js";
3
3
 
4
+ /** Validate the captured metadata extension without interpreting provider-specific payload keys.
5
+ * Keep identity bounded because the incremental checkpoint stores it across segments.
6
+ */
7
+ export function observeResponsesEnvelope(
8
+ state: { responseId?: string; invalid?: boolean },
9
+ event: RecordValue,
10
+ ) {
11
+ if (event.type === "keepalive" && count(event.sequence_number) === undefined)
12
+ state.invalid = true;
13
+ const metadata = event.type === "response.metadata";
14
+ if (
15
+ metadata &&
16
+ (count(event.sequence_number) === undefined ||
17
+ event.metadata === null ||
18
+ typeof event.metadata !== "object" ||
19
+ Array.isArray(event.metadata))
20
+ )
21
+ state.invalid = true;
22
+ const id = metadata ? event.response_id : object(event.response).id;
23
+ if (metadata || id !== undefined) {
24
+ if (
25
+ typeof id !== "string" ||
26
+ !id.length ||
27
+ id.length > 256 ||
28
+ (state.responseId !== undefined && state.responseId !== id)
29
+ )
30
+ state.invalid = true;
31
+ else state.responseId = id;
32
+ }
33
+ }
34
+
4
35
  /** Reconstruct only emitted Responses content; a completed item is not a completed call. */
5
36
  export function assembleResponsesStream(events: RecordValue[]) {
6
37
  const response: RecordValue = {};
7
38
  const items = new Map<number, RecordValue>();
39
+ const envelope: { responseId?: string; invalid?: boolean } = {};
40
+ const metadataEvents: RecordValue[] = [];
8
41
  let terminal = false;
9
42
  let terminalUsage = false;
10
43
  let terminalSnapshot = false;
@@ -13,6 +46,14 @@ export function assembleResponsesStream(events: RecordValue[]) {
13
46
  let unsupported = false;
14
47
  for (const event of events) {
15
48
  const type = String(event.type);
49
+ observeResponsesEnvelope(envelope, event);
50
+ if (type === "response.metadata") {
51
+ recognized = true;
52
+ // Preserve every update, including its identity and sequence, separately from
53
+ // response.metadata in lifecycle snapshots (a distinct provider field).
54
+ metadataEvents.push(event);
55
+ continue;
56
+ }
16
57
  if (type === "keepalive") {
17
58
  // This control frame carries no response content, identity or final usage.
18
59
  recognized = true;
@@ -172,7 +213,15 @@ export function assembleResponsesStream(events: RecordValue[]) {
172
213
  ...emitted.filter((item) => typeof item.id !== "string" || !snapshotIds.has(item.id)),
173
214
  ];
174
215
  }
175
- return { response, terminal, terminalUsage, recognized, invalid, unsupported };
216
+ return {
217
+ response,
218
+ terminal,
219
+ terminalUsage,
220
+ recognized,
221
+ invalid: invalid || !!envelope.invalid,
222
+ unsupported,
223
+ metadataEvents,
224
+ };
176
225
  }
177
226
 
178
227
  export function responsesMessages(output: unknown): RecordValue[] {