@demicodes/core 0.10.3 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -11,6 +11,14 @@ type ImageSource = {
11
11
  type: 'url';
12
12
  url: string;
13
13
  };
14
+ type VideoSource = {
15
+ type: 'binary';
16
+ data: Uint8Array;
17
+ mediaType: string;
18
+ } | {
19
+ type: 'url';
20
+ url: string;
21
+ };
14
22
  interface DocumentSource {
15
23
  data: Uint8Array;
16
24
  mediaType: string;
@@ -22,6 +30,9 @@ type UserContentBlock = {
22
30
  } | {
23
31
  type: 'image';
24
32
  source: ImageSource;
33
+ } | {
34
+ type: 'video';
35
+ source: VideoSource;
25
36
  } | {
26
37
  type: 'document';
27
38
  source: DocumentSource;
@@ -33,12 +44,19 @@ interface Base64ImageSource {
33
44
  mediaType: string;
34
45
  data: string;
35
46
  }
47
+ interface Base64VideoSource {
48
+ mediaType: string;
49
+ data: string;
50
+ }
36
51
  type ToolResultContentBlock = {
37
52
  type: 'text';
38
53
  text: string;
39
54
  } | {
40
55
  type: 'image';
41
56
  source: Base64ImageSource;
57
+ } | {
58
+ type: 'video';
59
+ source: Base64VideoSource;
42
60
  };
43
61
  interface TokenUsage {
44
62
  inputTokens: number;
@@ -48,7 +66,10 @@ interface TokenUsage {
48
66
  }
49
67
  /** A `TokenUsage` with every counter at zero. */
50
68
  declare function zeroUsage(): TokenUsage;
51
- type FileExtension = 'png' | 'jpg' | 'jpeg' | 'gif' | 'webp' | 'pdf';
69
+ type ImageFileExtension = 'png' | 'jpg' | 'jpeg' | 'gif' | 'webp';
70
+ type VideoFileExtension = 'mp4' | 'mov' | 'webm' | 'm4v';
71
+ type FileExtension = ImageFileExtension | VideoFileExtension | 'pdf';
72
+ declare const VIDEO_FILE_EXTENSIONS: readonly VideoFileExtension[];
52
73
  type ThinkingEffort = string;
53
74
  type ThinkingSummary = 'auto' | 'concise' | 'detailed' | 'off' | 'on';
54
75
  type ThinkingCapability = {
@@ -90,6 +111,21 @@ interface Model {
90
111
  thinking: ThinkingCapability[];
91
112
  acceptedExtensions: FileExtension[];
92
113
  }
114
+ declare function modelAcceptsVideo(model: Model): boolean;
115
+ type ModelMediaKind = 'image' | 'video';
116
+ interface ModelMediaType {
117
+ mediaType: string;
118
+ kind: ModelMediaKind;
119
+ extension: ImageFileExtension | VideoFileExtension;
120
+ }
121
+ declare function modelMediaTypeFor(mediaType: string): ModelMediaType | null;
122
+ /** Whether this model accepts the given media type natively (per its catalog extensions). */
123
+ declare function modelAcceptsMediaType(model: Model, mediaType: string): boolean;
124
+ /**
125
+ * Detect a model-media type from a byte stream's magic numbers. Returns null
126
+ * for anything outside the closed set — callers must not guess further.
127
+ */
128
+ declare function sniffModelMediaType(bytes: Uint8Array): ModelMediaType | null;
93
129
  interface ModelSelection {
94
130
  providerId: string;
95
131
  model: Model;
@@ -97,6 +133,14 @@ interface ModelSelection {
97
133
  serviceTierId?: string | null;
98
134
  }
99
135
  type ToolCallStatus = 'executing' | 'completed' | 'error';
136
+ interface ProviderErrorDiagnostics {
137
+ source: 'http' | 'stream' | 'transport' | 'unknown';
138
+ clientRequestId?: string;
139
+ providerRequestId?: string;
140
+ providerResponseId?: string;
141
+ providerCode?: string;
142
+ httpStatus?: number;
143
+ }
100
144
  type Block = {
101
145
  type: 'user';
102
146
  id: string;
@@ -150,7 +194,13 @@ type Block = {
150
194
  status: ToolCallStatus;
151
195
  streamingOutput: ToolResultContentBlock[];
152
196
  output: ToolResultContentBlock[];
153
- metadata: unknown | null;
197
+ /**
198
+ * Bounded UI-facing enhancement data, typed by the tool's owning layer.
199
+ * Never replayed to the model. Must not embed unbounded payloads (full
200
+ * command output, file bodies, raw or base64 bytes) — anything unbounded
201
+ * lives in a command artifact or blob and is referenced by id.
202
+ */
203
+ view: unknown | null;
154
204
  } | {
155
205
  type: 'response';
156
206
  id: string;
@@ -164,6 +214,7 @@ type Block = {
164
214
  model: ModelSelection;
165
215
  message: string;
166
216
  code: string | null;
217
+ diagnostics?: ProviderErrorDiagnostics;
167
218
  } | {
168
219
  type: 'abort';
169
220
  id: string;
@@ -200,10 +251,5 @@ interface QueuedMessage {
200
251
  interface Transcript {
201
252
  blocks: Block[];
202
253
  }
203
- interface AgentSessionCoreState {
204
- transcript: Transcript;
205
- phase: SessionPhase;
206
- queue: QueuedMessage[];
207
- }
208
254
  //#endregion
209
- export { AgentSessionCoreState, Base64ImageSource, Block, BlockMeta, DocumentSource, FileExtension, ImageSource, Model, ModelSelection, QueuedMessage, SessionPhase, ThinkingCapability, ThinkingConfig, ThinkingEffort, ThinkingSummary, TokenUsage, ToolCallStatus, ToolResultContentBlock, Transcript, UserContentBlock, zeroUsage };
255
+ export { Base64ImageSource, Base64VideoSource, Block, BlockMeta, DocumentSource, FileExtension, ImageFileExtension, ImageSource, Model, ModelMediaKind, ModelMediaType, ModelSelection, ProviderErrorDiagnostics, QueuedMessage, SessionPhase, ThinkingCapability, ThinkingConfig, ThinkingEffort, ThinkingSummary, TokenUsage, ToolCallStatus, ToolResultContentBlock, Transcript, UserContentBlock, VIDEO_FILE_EXTENSIONS, VideoFileExtension, VideoSource, modelAcceptsMediaType, modelAcceptsVideo, modelMediaTypeFor, sniffModelMediaType, zeroUsage };
package/dist/index.mjs CHANGED
@@ -8,5 +8,91 @@ function zeroUsage() {
8
8
  cacheWriteTokens: 0
9
9
  };
10
10
  }
11
+ const VIDEO_FILE_EXTENSIONS = [
12
+ "mp4",
13
+ "mov",
14
+ "webm",
15
+ "m4v"
16
+ ];
17
+ function modelAcceptsVideo(model) {
18
+ return VIDEO_FILE_EXTENSIONS.some((extension) => model.acceptedExtensions.includes(extension));
19
+ }
20
+ const MODEL_MEDIA_TYPES = [
21
+ {
22
+ mediaType: "image/png",
23
+ kind: "image",
24
+ extension: "png"
25
+ },
26
+ {
27
+ mediaType: "image/jpeg",
28
+ kind: "image",
29
+ extension: "jpeg"
30
+ },
31
+ {
32
+ mediaType: "image/gif",
33
+ kind: "image",
34
+ extension: "gif"
35
+ },
36
+ {
37
+ mediaType: "image/webp",
38
+ kind: "image",
39
+ extension: "webp"
40
+ },
41
+ {
42
+ mediaType: "video/mp4",
43
+ kind: "video",
44
+ extension: "mp4"
45
+ },
46
+ {
47
+ mediaType: "video/x-m4v",
48
+ kind: "video",
49
+ extension: "m4v"
50
+ },
51
+ {
52
+ mediaType: "video/quicktime",
53
+ kind: "video",
54
+ extension: "mov"
55
+ },
56
+ {
57
+ mediaType: "video/webm",
58
+ kind: "video",
59
+ extension: "webm"
60
+ }
61
+ ];
62
+ function modelMediaTypeFor(mediaType) {
63
+ return MODEL_MEDIA_TYPES.find((entry) => entry.mediaType === mediaType) ?? null;
64
+ }
65
+ /** Whether this model accepts the given media type natively (per its catalog extensions). */
66
+ function modelAcceptsMediaType(model, mediaType) {
67
+ const entry = modelMediaTypeFor(mediaType);
68
+ if (!entry) return false;
69
+ if (model.acceptedExtensions.includes(entry.extension)) return true;
70
+ return entry.extension === "jpeg" && model.acceptedExtensions.includes("jpg");
71
+ }
72
+ /**
73
+ * Detect a model-media type from a byte stream's magic numbers. Returns null
74
+ * for anything outside the closed set — callers must not guess further.
75
+ */
76
+ function sniffModelMediaType(bytes) {
77
+ if (bytes.length < 12) return null;
78
+ const at = (index) => bytes[index] ?? 0;
79
+ const ascii = (start, length) => {
80
+ let out = "";
81
+ for (let i = start; i < start + length && i < bytes.length; i += 1) out += String.fromCharCode(at(i));
82
+ return out;
83
+ };
84
+ if (at(0) === 137 && ascii(1, 3) === "PNG") return modelMediaTypeFor("image/png");
85
+ if (at(0) === 255 && at(1) === 216 && at(2) === 255) return modelMediaTypeFor("image/jpeg");
86
+ if (ascii(0, 6) === "GIF87a" || ascii(0, 6) === "GIF89a") return modelMediaTypeFor("image/gif");
87
+ if (ascii(0, 4) === "RIFF" && ascii(8, 4) === "WEBP") return modelMediaTypeFor("image/webp");
88
+ if (at(0) === 26 && at(1) === 69 && at(2) === 223 && at(3) === 163) return modelMediaTypeFor("video/webm");
89
+ if (ascii(4, 4) === "ftyp") {
90
+ const brand = ascii(8, 4);
91
+ if (brand === "qt ") return modelMediaTypeFor("video/quicktime");
92
+ if (brand.startsWith("M4V")) return modelMediaTypeFor("video/x-m4v");
93
+ return modelMediaTypeFor("video/mp4");
94
+ }
95
+ return null;
96
+ }
11
97
  //#endregion
12
- export { zeroUsage };
98
+ export { VIDEO_FILE_EXTENSIONS, modelAcceptsMediaType, modelAcceptsVideo, modelMediaTypeFor, sniffModelMediaType, zeroUsage };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@demicodes/core",
3
3
  "description": "Core data types and shared domain primitives for the Demi agent toolkit.",
4
- "version": "0.10.3",
4
+ "version": "0.11.0",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "exports": {