super-dsh 0.1.0 → 0.1.2

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 (178) hide show
  1. package/agent-agy/bridge/agy_bridge.py +250 -0
  2. package/agent-agy/bridge/gemini_openai_server.mjs +98 -0
  3. package/agent-agy/cordis.patch.yml +49 -0
  4. package/agent-agy/dist/adapter.d.ts +15 -0
  5. package/agent-agy/dist/adapter.js +42 -0
  6. package/agent-agy/dist/agent-preset-agy.d.ts +47 -0
  7. package/agent-agy/dist/agent-preset-agy.js +169 -0
  8. package/agent-agy/dist/agent-preset-projection.d.ts +31 -0
  9. package/agent-agy/dist/agent-preset-projection.js +33 -0
  10. package/agent-agy/dist/agent.d.ts +137 -0
  11. package/agent-agy/dist/agent.js +493 -0
  12. package/agent-agy/dist/agy-cli-client.d.ts +137 -0
  13. package/agent-agy/dist/agy-cli-client.js +301 -0
  14. package/agent-agy/dist/agy-client.d.ts +160 -0
  15. package/agent-agy/dist/agy-client.js +252 -0
  16. package/agent-agy/dist/agy-sessions.d.ts +24 -0
  17. package/agent-agy/dist/agy-sessions.js +116 -0
  18. package/agent-agy/dist/agy-store.d.ts +39 -0
  19. package/agent-agy/dist/agy-store.js +83 -0
  20. package/agent-agy/dist/inbox.d.ts +26 -0
  21. package/agent-agy/dist/inbox.js +53 -0
  22. package/agent-agy/dist/index.d.ts +80 -0
  23. package/agent-agy/dist/index.js +505 -0
  24. package/agent-agy/dist/models.d.ts +41 -0
  25. package/agent-agy/dist/models.js +74 -0
  26. package/agent-agy/dist/world-plugin.d.ts +9 -0
  27. package/agent-agy/dist/world-plugin.js +97 -0
  28. package/agent-agy/package.json +64 -0
  29. package/agent-claude/cordis.patch.yml +42 -0
  30. package/agent-claude/dist/adapter.js +62 -0
  31. package/agent-claude/dist/agent-preset-claude.js +169 -0
  32. package/agent-claude/dist/agent-preset-projection.js +30 -0
  33. package/agent-claude/dist/agent.js +1271 -0
  34. package/agent-claude/dist/claude-client.js +357 -0
  35. package/agent-claude/dist/claude-events.js +223 -0
  36. package/agent-claude/dist/claude-home.js +29 -0
  37. package/agent-claude/dist/commands.js +182 -0
  38. package/agent-claude/dist/content.js +134 -0
  39. package/agent-claude/dist/inbox.js +53 -0
  40. package/agent-claude/dist/index.js +555 -0
  41. package/agent-claude/dist/input-queue.js +64 -0
  42. package/agent-claude/dist/interaction.js +271 -0
  43. package/agent-claude/dist/models.js +158 -0
  44. package/agent-claude/dist/permission.js +120 -0
  45. package/agent-claude/dist/session-id.js +20 -0
  46. package/agent-claude/dist/session-map.js +165 -0
  47. package/agent-claude/dist/world-plugin.js +14 -0
  48. package/agent-claude/package.json +74 -0
  49. package/agent-codex/README.md +74 -0
  50. package/agent-codex/cordis.patch.yml +77 -0
  51. package/agent-codex/dist/adapter.js +55 -0
  52. package/agent-codex/dist/agent-preset-codex.js +171 -0
  53. package/agent-codex/dist/agent-preset-projection.js +37 -0
  54. package/agent-codex/dist/agent.js +1056 -0
  55. package/agent-codex/dist/app-home.js +65 -0
  56. package/agent-codex/dist/codex-client.js +469 -0
  57. package/agent-codex/dist/codex-events.js +297 -0
  58. package/agent-codex/dist/codex-store.js +190 -0
  59. package/agent-codex/dist/inbox.js +53 -0
  60. package/agent-codex/dist/index.js +605 -0
  61. package/agent-codex/dist/models.js +152 -0
  62. package/agent-codex/dist/permission.js +71 -0
  63. package/agent-codex/dist/session-map.js +170 -0
  64. package/agent-codex/dist/spike.js +46 -0
  65. package/agent-codex/dist/world-plugin.js +96 -0
  66. package/agent-codex/package.json +78 -0
  67. package/agent-hermes/README.md +144 -0
  68. package/agent-hermes/cordis.patch.yml +83 -0
  69. package/agent-hermes/dist/adapter.js +83 -0
  70. package/agent-hermes/dist/agent-preset-hermes.js +171 -0
  71. package/agent-hermes/dist/agent-preset-projection.js +34 -0
  72. package/agent-hermes/dist/agent.js +1068 -0
  73. package/agent-hermes/dist/hermes-client.js +953 -0
  74. package/agent-hermes/dist/hermes-events.js +289 -0
  75. package/agent-hermes/dist/hermes-store.js +158 -0
  76. package/agent-hermes/dist/inbox.js +53 -0
  77. package/agent-hermes/dist/index.js +541 -0
  78. package/agent-hermes/dist/models.js +324 -0
  79. package/agent-hermes/dist/permission.js +60 -0
  80. package/agent-hermes/dist/world-plugin.js +101 -0
  81. package/agent-hermes/package.json +76 -0
  82. package/agent-hub/cordis.patch.yml +12 -0
  83. package/agent-hub/dist/agent-roster.d.ts +34 -0
  84. package/agent-hub/dist/agent-roster.js +27 -0
  85. package/agent-hub/dist/carrier.d.ts +43 -0
  86. package/agent-hub/dist/carrier.js +241 -0
  87. package/agent-hub/dist/client-shim.d.ts +28 -0
  88. package/agent-hub/dist/client-shim.js +251 -0
  89. package/agent-hub/dist/envelope.d.ts +54 -0
  90. package/agent-hub/dist/envelope.js +92 -0
  91. package/agent-hub/dist/gateway.d.ts +28 -0
  92. package/agent-hub/dist/gateway.js +18 -0
  93. package/agent-hub/dist/index-pass.d.ts +22 -0
  94. package/agent-hub/dist/index-pass.js +47 -0
  95. package/agent-hub/dist/index.d.ts +29 -0
  96. package/agent-hub/dist/index.js +29 -0
  97. package/agent-hub/dist/labels.d.ts +45 -0
  98. package/agent-hub/dist/labels.js +83 -0
  99. package/agent-hub/dist/ownership.d.ts +37 -0
  100. package/agent-hub/dist/ownership.js +54 -0
  101. package/agent-hub/dist/roster.d.ts +28 -0
  102. package/agent-hub/dist/roster.js +38 -0
  103. package/agent-hub/dist/rpc.d.ts +38 -0
  104. package/agent-hub/dist/rpc.js +52 -0
  105. package/agent-hub/dist/spawn-world.d.ts +46 -0
  106. package/agent-hub/dist/spawn-world.js +72 -0
  107. package/agent-hub/dist/targets.d.ts +33 -0
  108. package/agent-hub/dist/targets.js +30 -0
  109. package/agent-hub/dist/world-entry.d.ts +31 -0
  110. package/agent-hub/dist/world-entry.js +51 -0
  111. package/agent-hub/dist/world-host.d.ts +69 -0
  112. package/agent-hub/dist/world-host.js +44 -0
  113. package/agent-hub/dist/world-join.d.ts +16 -0
  114. package/agent-hub/dist/world-join.js +122 -0
  115. package/agent-hub/dist/world-mount.d.ts +52 -0
  116. package/agent-hub/dist/world-mount.js +52 -0
  117. package/agent-hub/dist/world-mux.d.ts +72 -0
  118. package/agent-hub/dist/world-mux.js +224 -0
  119. package/agent-hub/dist/world-provision.d.ts +20 -0
  120. package/agent-hub/dist/world-provision.js +122 -0
  121. package/agent-hub/dist/world-web-server.d.ts +162 -0
  122. package/agent-hub/dist/world-web-server.js +248 -0
  123. package/agent-hub/lib/client/index.js +242 -0
  124. package/agent-hub/package.json +65 -0
  125. package/agent-omp/README.md +77 -0
  126. package/agent-omp/cordis.patch.yml +92 -0
  127. package/agent-omp/dist/adapter.js +36 -0
  128. package/agent-omp/dist/agent-preset-omp.js +171 -0
  129. package/agent-omp/dist/agent-preset-projection.js +36 -0
  130. package/agent-omp/dist/agent.js +1145 -0
  131. package/agent-omp/dist/app-home.js +86 -0
  132. package/agent-omp/dist/discovery.js +116 -0
  133. package/agent-omp/dist/inbox.js +53 -0
  134. package/agent-omp/dist/index.js +574 -0
  135. package/agent-omp/dist/knobs.js +50 -0
  136. package/agent-omp/dist/lazy-rpc.js +161 -0
  137. package/agent-omp/dist/mobile/gesture.js +148 -0
  138. package/agent-omp/dist/mobile/zoom-guard.js +294 -0
  139. package/agent-omp/dist/mobile-boot.js +38 -0
  140. package/agent-omp/dist/models.js +299 -0
  141. package/agent-omp/dist/omp-cli.js +147 -0
  142. package/agent-omp/dist/omp-disk-discovery.js +178 -0
  143. package/agent-omp/dist/omp-store.js +518 -0
  144. package/agent-omp/dist/pairing.js +45 -0
  145. package/agent-omp/dist/permission.js +96 -0
  146. package/agent-omp/dist/protocol.js +13 -0
  147. package/agent-omp/dist/rpc-types.js +1 -0
  148. package/agent-omp/dist/sdk-client.js +378 -0
  149. package/agent-omp/dist/sidecar-client.js +195 -0
  150. package/agent-omp/dist/store/adapter.js +47 -0
  151. package/agent-omp/dist/store/db.js +210 -0
  152. package/agent-omp/dist/store/index.js +59 -0
  153. package/agent-omp/dist/store/reconcile.js +51 -0
  154. package/agent-omp/dist/store/schema.js +40 -0
  155. package/agent-omp/dist/world-plugin.js +96 -0
  156. package/agent-omp/package.json +97 -0
  157. package/agent-omp/sidecar/main.ts +481 -0
  158. package/agent-pi/README.md +67 -0
  159. package/agent-pi/cordis.patch.yml +80 -0
  160. package/agent-pi/dist/adapter.js +53 -0
  161. package/agent-pi/dist/agent-preset-pi.js +169 -0
  162. package/agent-pi/dist/agent-preset-projection.js +29 -0
  163. package/agent-pi/dist/agent.js +949 -0
  164. package/agent-pi/dist/inbox.js +53 -0
  165. package/agent-pi/dist/index.js +595 -0
  166. package/agent-pi/dist/knobs.js +24 -0
  167. package/agent-pi/dist/models.js +200 -0
  168. package/agent-pi/dist/permission.js +66 -0
  169. package/agent-pi/dist/pi-client.js +224 -0
  170. package/agent-pi/dist/pi-events.js +155 -0
  171. package/agent-pi/dist/pi-home.js +55 -0
  172. package/agent-pi/dist/safe-json.js +25 -0
  173. package/agent-pi/dist/session-map.js +119 -0
  174. package/agent-pi/dist/world-plugin.js +97 -0
  175. package/agent-pi/package.json +77 -0
  176. package/cordis.patch.yml +22 -19
  177. package/package.json +88 -25
  178. package/client.js +0 -4
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Claude Code's observed slash commands, registered onto `ctx.commands`.
3
+ *
4
+ * Claude owns a command surface (`session_init.slash_commands`): `/mcp`,
5
+ * `/clear`, `/review`, plugin-namespaced commands, and so on. DSH exposes its
6
+ * own registry to the composer, so the adapter mirrors each observed Claude
7
+ * command there and lets the user pick it from the same menu.
8
+ *
9
+ * Two deliberate rules:
10
+ *
11
+ * - **Every registered id is `claude-<name>`.** Prefixing is total — the id is
12
+ * the only thing this module writes to the shared registry, so it must be
13
+ * collision-free with DSH's own `/compact`, `/plan`, `/permission`, … AND
14
+ * self-explanatory about its owner. A name that already carries the prefix is
15
+ * still prefixed once more (`claude-mcp` -> `claude-claude-mcp`): de-prefixing
16
+ * would alias two genuinely distinct observed names onto one id.
17
+ * - **The handler forwards, it never renders.** `submit` receives
18
+ * `/mcp` plus the raw tail exactly as the user typed it (the registry hands
19
+ * the tail through unnormalized), so Claude's own command parser sees its
20
+ * original line. The panel/output for the command flows back through the
21
+ * ordinary transcript projection.
22
+ *
23
+ * The invocation's id is sanitized for DSH's command-id grammar
24
+ * (`^[a-z][a-z0-9_-]*$`) — lowercase, invalid runs become `-` — but the
25
+ * FORWARDED line keeps the observed spelling, so sanitizing is invisible to
26
+ * Claude.
27
+ */
28
+ // No Cordis import: the runtime surface this module needs is described
29
+ // structurally below, which keeps the module loadable (and testable) without a
30
+ // Cordis host, and keeps the adapter's runtime dependency set unchanged.
31
+ /** DSH's command-id grammar (`@deepseek-ai/dsh-commands`' `COMMAND_NAME`). */
32
+ const COMMAND_ID_BODY = /[^a-z0-9_-]+/gu;
33
+ /**
34
+ * Sanitize one observed Claude name into a `claude-` prefixed DSH command id.
35
+ *
36
+ * The prefix guarantees the grammar's leading-lowercase-letter requirement, so
37
+ * the only work left is mapping the body to `[a-z0-9_-]`. The mapping is total
38
+ * and deterministic: uppercase folds, every invalid run becomes one `-`.
39
+ *
40
+ * @returns the command id, or `undefined` when nothing usable is left.
41
+ */
42
+ function claudeCommandId(observed) {
43
+ const body = observed.toLowerCase().replace(COMMAND_ID_BODY, "-");
44
+ return body === "" ? undefined : `claude-${body}`;
45
+ }
46
+ /**
47
+ * Build the discovery summary. The registry rejects an empty description, so a
48
+ * missing/blank observed one falls back to a constant; a real one is prefixed
49
+ * so every entry in the menu declares its owner.
50
+ */
51
+ function claudeDescription(observed) {
52
+ const text = typeof observed === "string" ? observed.trim() : "";
53
+ return text === "" ? "Claude Code slash command" : `Claude Code: ${text}`;
54
+ }
55
+ /** The observed name, trimmed; blank/non-string input yields `""` (skip). */
56
+ function observedName(command) {
57
+ const raw = command?.name;
58
+ return typeof raw === "string" ? raw.trim() : "";
59
+ }
60
+ /**
61
+ * Normalize ONE reported entry — a bare name string (`session_init.slash_commands`
62
+ * is `string[]`) or an SDK `SlashCommand` object (`supportedCommands()` carries
63
+ * the description and argument hint) — into the shape this module registers.
64
+ *
65
+ * @returns the entry, or `undefined` when the report carries no usable name.
66
+ */
67
+ function reportedEntry(raw) {
68
+ const record = typeof raw === "string"
69
+ ? { name: raw }
70
+ : typeof raw === "object" && raw !== null ? raw : undefined;
71
+ if (record === undefined)
72
+ return undefined;
73
+ const name = typeof record.name === "string" ? record.name.trim() : "";
74
+ if (name === "")
75
+ return undefined;
76
+ const description = typeof record.description === "string" ? record.description.trim() : "";
77
+ const argumentHint = typeof record.argumentHint === "string" ? record.argumentHint.trim() : "";
78
+ return {
79
+ name,
80
+ ...description === "" ? {} : { description },
81
+ ...argumentHint === "" ? {} : { argumentHint },
82
+ };
83
+ }
84
+ /**
85
+ * Normalize everything Claude reported about its command surface into the
86
+ * registration list, de-duplicated by name (first report wins — the SDK's
87
+ * `aliases` are alternate spellings of the same command, deliberately NOT
88
+ * separate menu entries).
89
+ *
90
+ * Accepts the `session_init` name list and the richer `supportedCommands()`
91
+ * objects through the same door, so the two observation sources cannot drift
92
+ * in their filtering rules.
93
+ *
94
+ * @param raw - the reported array, in either shape; anything else yields `[]`.
95
+ * @returns the usable entries in report order.
96
+ */
97
+ export function slashCommandsFromReported(raw) {
98
+ if (!Array.isArray(raw))
99
+ return [];
100
+ const seen = new Set();
101
+ const entries = [];
102
+ for (const item of raw) {
103
+ const entry = reportedEntry(item);
104
+ if (entry === undefined || seen.has(entry.name))
105
+ continue;
106
+ seen.add(entry.name);
107
+ entries.push(entry);
108
+ }
109
+ return entries;
110
+ }
111
+ /**
112
+ * Mirror every observed Claude slash command onto `ctx.commands`.
113
+ *
114
+ * Skips (never throws on) an observed entry whose name is absent, non-string,
115
+ * or blank; de-duplicates by resulting command id so a repeated observation
116
+ * cannot double-register; and rolls back (releases) every registration already
117
+ * made when a later `register` throws, so a partial mirror never leaks.
118
+ *
119
+ * @param ctx - a context whose `commands` registry is reachable.
120
+ * @param deps - the observed command list plus the exact-line submit sink.
121
+ * @returns a disposer that releases EVERY registration this call made (once).
122
+ */
123
+ export function registerClaudeCommands(ctx, deps) {
124
+ const disposers = [];
125
+ const registered = new Set();
126
+ let disposed = false;
127
+ /** Release every registration made so far; the returned disposer, guarded. */
128
+ const disposeAll = () => {
129
+ if (disposed)
130
+ return;
131
+ disposed = true;
132
+ let firstError;
133
+ for (const dispose of disposers.splice(0)) {
134
+ try {
135
+ dispose();
136
+ }
137
+ catch (error) {
138
+ // One bad disposer must not strand the others: collect and re-raise.
139
+ if (firstError === undefined)
140
+ firstError = error;
141
+ }
142
+ }
143
+ if (firstError !== undefined)
144
+ throw firstError;
145
+ };
146
+ try {
147
+ for (const command of deps.listSlashCommands() ?? []) {
148
+ const observed = observedName(command);
149
+ if (observed === "")
150
+ continue;
151
+ const name = claudeCommandId(observed);
152
+ if (name === undefined || registered.has(name))
153
+ continue;
154
+ registered.add(name);
155
+ const hint = command?.argumentHint;
156
+ const trimmedHint = typeof hint === "string" ? hint.trim() : "";
157
+ const dispose = ctx.commands.register({
158
+ name,
159
+ description: claudeDescription(command?.description),
160
+ ...trimmedHint === "" ? {} : { input: { hint: trimmedHint } },
161
+ handler: (invocation) => {
162
+ deps.submit(invocation.agent, `/${observed}${invocation.rawInput}`);
163
+ return { kind: "success" };
164
+ },
165
+ });
166
+ if (typeof dispose === "function")
167
+ disposers.push(dispose);
168
+ }
169
+ }
170
+ catch (error) {
171
+ // A partial registration must not leak: release what landed, then report
172
+ // the original failure (a disposer's own throw must not mask it).
173
+ try {
174
+ disposeAll();
175
+ }
176
+ catch {
177
+ /* the registration failure below stays the reported one */
178
+ }
179
+ throw error;
180
+ }
181
+ return disposeAll;
182
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * DSH content blocks -> Anthropic message content blocks.
3
+ *
4
+ * The paste/prompt UI is DSH's own; the adapter owns the transcoding into
5
+ * Claude's wire shape (spec ruling R14). A block whose payload cannot be
6
+ * resolved is SKIPPED AND REPORTED: an unattachable image must never silently
7
+ * vanish, and an unusable placeholder must never be sent to the runtime.
8
+ *
9
+ * The module is deliberately PURE — no SDK import and no I/O. It produces plain
10
+ * JSON blocks and the caller injects whatever attachment reader it owns, so the
11
+ * projection can be pinned by a unit test without a store, a CLI, or a session.
12
+ *
13
+ * ## Skip policy (every skip is loud)
14
+ *
15
+ * - a non-object entry, a missing/empty/non-string text, or an empty text block
16
+ * (the Anthropic API rejects empty text blocks, so normalizing one away is a
17
+ * reported drop, not a silent trim);
18
+ * - an unknown block `type`;
19
+ * - an `image`/`file` with neither inline `data` nor a resolvable
20
+ * `attachmentId`;
21
+ * - an `attachmentId` the injected reader cannot resolve (or one that throws —
22
+ * the reader's failure is contained here and becomes a reported skip);
23
+ * - a missing/empty `mediaType`, or a media type that is not `image/*`: the
24
+ * output must never carry `media_type: undefined` or a non-image source;
25
+ * - ANY `file` block. DSH's `file` block is a verbatim attachment reference —
26
+ * the harness contract is that files never reach a provider natively and are
27
+ * projected to deterministic handle text instead, so this adapter must not
28
+ * launder one into an image block. It is reported instead.
29
+ */
30
+ /** Whether a media type may ride an Anthropic base64 image source. */
31
+ function isImageMediaType(mediaType) {
32
+ return mediaType.startsWith("image/");
33
+ }
34
+ /** A non-empty string field, or undefined when absent/blank/unusable. */
35
+ function stringField(value) {
36
+ return typeof value === "string" && value !== "" ? value : undefined;
37
+ }
38
+ /** Human-readable detail for a contained reader failure. */
39
+ function errorDetail(error) {
40
+ const message = error instanceof Error ? error.message : String(error);
41
+ return message === "" ? "unknown error" : message;
42
+ }
43
+ /**
44
+ * Transcode DSH user content blocks into Anthropic input blocks.
45
+ *
46
+ * @param blocks - DSH user content blocks in message order. Entries are read
47
+ * defensively: a null/undefined/non-object member is reported, not fatal.
48
+ * @param readAttachment - synchronous resolver for a durable attachment id.
49
+ * Returning `undefined` means "not resolvable" and becomes a reported skip;
50
+ * throwing is contained into a reported skip as well. A block carrying inline
51
+ * `data` never consults it.
52
+ * @returns the attachable blocks in input order plus one actionable reason per
53
+ * block that could not be attached.
54
+ */
55
+ export function toClaudeContent(blocks, readAttachment) {
56
+ const content = [];
57
+ const skipped = [];
58
+ const source = Array.isArray(blocks) ? blocks : [];
59
+ for (let index = 0; index < source.length; index += 1) {
60
+ const entry = source[index];
61
+ if (entry === null || entry === undefined || typeof entry !== "object") {
62
+ skipped.push(`block at index ${index}: not a content block object`);
63
+ continue;
64
+ }
65
+ const block = entry;
66
+ if (block.type === "text") {
67
+ const text = block.text;
68
+ if (typeof text !== "string") {
69
+ skipped.push(`text block at index ${index}: missing text`);
70
+ continue;
71
+ }
72
+ if (text === "") {
73
+ skipped.push(`text block at index ${index}: empty text`);
74
+ continue;
75
+ }
76
+ // Byte-exact, and one output block per input block: consecutive text
77
+ // blocks are legal on the wire, and merging them would change the shape.
78
+ content.push({ type: "text", text });
79
+ continue;
80
+ }
81
+ if (block.type !== "image" && block.type !== "file") {
82
+ skipped.push(`block at index ${index}: unknown block type ${JSON.stringify(block.type)}`);
83
+ continue;
84
+ }
85
+ if (block.type === "file") {
86
+ // DSH's `file` block is a verbatim attachment reference. The harness
87
+ // contract is that files never reach a provider natively (they are
88
+ // projected to deterministic handle text), so a file block is NEVER
89
+ // emitted as an image block here — even when its payload looks like a
90
+ // raster image. Reported instead, and never resolved through the image
91
+ // reader.
92
+ const fileMediaType = stringField(block.mediaType);
93
+ skipped.push(`file block at index ${index}: verbatim file references cannot be attached to Claude` +
94
+ (fileMediaType === undefined ? "" : ` (mediaType "${fileMediaType}")`));
95
+ continue;
96
+ }
97
+ let mediaType = stringField(block.mediaType);
98
+ let data = stringField(block.data);
99
+ const attachmentId = stringField(block.attachmentId);
100
+ if (data === undefined && attachmentId !== undefined) {
101
+ let resolved;
102
+ try {
103
+ resolved = readAttachment(attachmentId);
104
+ }
105
+ catch (error) {
106
+ skipped.push(`${block.type} block at index ${index}: reading attachment "${attachmentId}" failed (${errorDetail(error)})`);
107
+ continue;
108
+ }
109
+ if (resolved !== undefined && resolved !== null && typeof resolved === "object") {
110
+ if (mediaType === undefined)
111
+ mediaType = stringField(resolved.mediaType);
112
+ if (data === undefined)
113
+ data = stringField(resolved.data);
114
+ }
115
+ }
116
+ if (data === undefined) {
117
+ skipped.push(`${block.type} block at index ${index}: no inline data` +
118
+ (attachmentId === undefined
119
+ ? " and no attachmentId"
120
+ : ` and attachment "${attachmentId}" could not be resolved`));
121
+ continue;
122
+ }
123
+ if (mediaType === undefined) {
124
+ skipped.push(`${block.type} block at index ${index}: missing mediaType`);
125
+ continue;
126
+ }
127
+ if (!isImageMediaType(mediaType)) {
128
+ skipped.push(`${block.type} block at index ${index}: media type "${mediaType}" is not an image media type`);
129
+ continue;
130
+ }
131
+ content.push({ type: "image", source: { type: "base64", media_type: mediaType, data } });
132
+ }
133
+ return { content, skipped };
134
+ }
@@ -0,0 +1,53 @@
1
+ export class Inbox {
2
+ nextTurnList = [];
3
+ nextStepList = [];
4
+ get nextTurn() {
5
+ return this.nextTurnList;
6
+ }
7
+ get nextStep() {
8
+ return this.nextStepList;
9
+ }
10
+ clear() {
11
+ this.nextTurnList = [];
12
+ this.nextStepList = [];
13
+ }
14
+ append(target, message) {
15
+ this.list(target).push(message);
16
+ }
17
+ prepend(target, message) {
18
+ this.list(target).unshift(message);
19
+ }
20
+ replace(messageId, newMessage) {
21
+ const list = this.find(messageId);
22
+ if (list === undefined)
23
+ return false;
24
+ const index = list.findIndex((message) => message.id === messageId);
25
+ if (index < 0)
26
+ return false;
27
+ list.splice(index, 1, newMessage);
28
+ return true;
29
+ }
30
+ remove(messageId) {
31
+ const list = this.find(messageId);
32
+ if (list === undefined)
33
+ return false;
34
+ const index = list.findIndex((message) => message.id === messageId);
35
+ if (index < 0)
36
+ return false;
37
+ list.splice(index, 1);
38
+ return true;
39
+ }
40
+ splice(target, start, deleteCount, inserted) {
41
+ return this.list(target).splice(start, deleteCount, ...inserted);
42
+ }
43
+ list(target) {
44
+ return target === "next-turn" ? this.nextTurnList : this.nextStepList;
45
+ }
46
+ find(messageId) {
47
+ if (this.nextTurnList.some((message) => message.id === messageId))
48
+ return this.nextTurnList;
49
+ if (this.nextStepList.some((message) => message.id === messageId))
50
+ return this.nextStepList;
51
+ return undefined;
52
+ }
53
+ }