@adecore/agents-react 0.26.2 → 0.26.3

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.
@@ -112,6 +112,36 @@ function MarkdownLink({ href, children }) {
112
112
  function ExternalLink({ href, children }) {
113
113
  return (_jsx("a", { href: href, target: "_blank", rel: "noreferrer", children: children }));
114
114
  }
115
+ /*
116
+ * The path on the host's machine an image target names, or null for a URL and for a relative path
117
+ * nobody gave a folder for. react-markdown has already emptied a target of a scheme it distrusts.
118
+ */
119
+ function localImagePath(src, cwd) {
120
+ if (src === '' || /^[a-z][a-z0-9+.-]*:/i.test(src)) {
121
+ return null;
122
+ }
123
+ const target = hrefPath(src);
124
+ if (target.startsWith('/')) {
125
+ return target;
126
+ }
127
+ if (cwd === null) {
128
+ return null;
129
+ }
130
+ return `${cwd.replace(/\/+$/, '')}/${target.replace(/^\.\//, '')}`;
131
+ }
132
+ /* A markdown image, which only the host can read when it names a file on its machine. */
133
+ function MarkdownImage({ src, alt }) {
134
+ const { MarkdownImage: HostImage } = useChatHost();
135
+ const cwd = useFileLinkCwd();
136
+ const path = typeof src === 'string' ? localImagePath(src, cwd) : null;
137
+ if (HostImage === undefined || path === null) {
138
+ return _jsx("img", { src: src, alt: alt });
139
+ }
140
+ return _jsx(HostImage, { path: path, alt: alt ?? '' });
141
+ }
142
+ function PlainImage({ src, alt }) {
143
+ return _jsx("img", { src: src, alt: alt });
144
+ }
115
145
  /* A ```mermaid fence, which draws what it says. */
116
146
  function Diagram({ code }) {
117
147
  const { t } = useTranslation('agent-chat');
@@ -135,6 +165,7 @@ const components = {
135
165
  a({ href, children }) {
136
166
  return _jsx(MarkdownLink, { href: href, children: children });
137
167
  },
168
+ img: MarkdownImage,
138
169
  table({ children }) {
139
170
  // A table wider than the column scrolls on its own instead of pushing the thread sideways.
140
171
  return (_jsx("div", { className: "chat-table", children: _jsx("table", { children: children }) }));
@@ -146,7 +177,8 @@ const plainComponents = {
146
177
  code({ className, children }) {
147
178
  return (_jsx(MarkdownCode, { className: className, plain: true, children: children }));
148
179
  },
149
- a: ExternalLink
180
+ a: ExternalLink,
181
+ img: PlainImage
150
182
  };
151
183
  // A reply sits under the heading of its message, an `h3`, so its own headings start one level below
152
184
  // that. Only `aria-level` moves. The tag stays, since the styles and a copy of the thread read it.
package/dist/host.d.ts CHANGED
@@ -195,6 +195,10 @@ export interface ChatHost {
195
195
  ReadImage: ComponentType<{
196
196
  path: string;
197
197
  }> | null;
198
+ MarkdownImage?: ComponentType<{
199
+ path: string;
200
+ alt: string;
201
+ }>;
198
202
  code: {
199
203
  useMode(): 'light' | 'dark';
200
204
  useThemes(): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adecore/agents-react",
3
- "version": "0.26.2",
3
+ "version": "0.26.3",
4
4
  "description": "React agent chat threads, composers, approvals, provider accounts and usage views.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -67,11 +67,11 @@
67
67
  "test:visuals": "bun --config=integration.bunfig.toml --conditions=source test ./src/chat/visual-viewport.integration.test.ts"
68
68
  },
69
69
  "dependencies": {
70
- "@adecore/agent-contracts": "0.26.2",
71
- "@adecore/editor": "0.26.2",
72
- "@adecore/editor-react": "0.26.2",
73
- "@adecore/intelligent-ui": "0.26.2",
74
- "@adecore/merge": "0.26.2",
70
+ "@adecore/agent-contracts": "0.26.3",
71
+ "@adecore/editor": "0.26.3",
72
+ "@adecore/editor-react": "0.26.3",
73
+ "@adecore/intelligent-ui": "0.26.3",
74
+ "@adecore/merge": "0.26.3",
75
75
  "@codemirror/commands": "^6.11.1",
76
76
  "@codemirror/language": "^6.12.4",
77
77
  "@codemirror/state": "^6.7.6",
@@ -94,14 +94,14 @@
94
94
  "zustand": "^5.0.15"
95
95
  },
96
96
  "peerDependencies": {
97
- "@adecore/ui": "^0.26.2",
97
+ "@adecore/ui": "^0.26.3",
98
98
  "i18next": "^26.4.2",
99
99
  "react": "^19.3.0",
100
100
  "react-dom": "^19.3.0",
101
101
  "react-i18next": "^17.0.15"
102
102
  },
103
103
  "devDependencies": {
104
- "@adecore/ui": "0.26.2",
104
+ "@adecore/ui": "0.26.3",
105
105
  "@types/bun": "^1.4.2",
106
106
  "@types/react": "^19.3.0",
107
107
  "@types/react-dom": "^19.3.0",
@@ -161,6 +161,39 @@ function ExternalLink({ href, children }: { href?: string; children?: ReactNode
161
161
  );
162
162
  }
163
163
 
164
+ /*
165
+ * The path on the host's machine an image target names, or null for a URL and for a relative path
166
+ * nobody gave a folder for. react-markdown has already emptied a target of a scheme it distrusts.
167
+ */
168
+ function localImagePath(src: string, cwd: string | null): string | null {
169
+ if (src === '' || /^[a-z][a-z0-9+.-]*:/i.test(src)) {
170
+ return null;
171
+ }
172
+ const target = hrefPath(src);
173
+ if (target.startsWith('/')) {
174
+ return target;
175
+ }
176
+ if (cwd === null) {
177
+ return null;
178
+ }
179
+ return `${cwd.replace(/\/+$/, '')}/${target.replace(/^\.\//, '')}`;
180
+ }
181
+
182
+ /* A markdown image, which only the host can read when it names a file on its machine. */
183
+ function MarkdownImage({ src, alt }: { src?: string; alt?: string }) {
184
+ const { MarkdownImage: HostImage } = useChatHost();
185
+ const cwd = useFileLinkCwd();
186
+ const path = typeof src === 'string' ? localImagePath(src, cwd) : null;
187
+ if (HostImage === undefined || path === null) {
188
+ return <img src={src} alt={alt} />;
189
+ }
190
+ return <HostImage path={path} alt={alt ?? ''} />;
191
+ }
192
+
193
+ function PlainImage({ src, alt }: { src?: string; alt?: string }) {
194
+ return <img src={src} alt={alt} />;
195
+ }
196
+
164
197
  /* A ```mermaid fence, which draws what it says. */
165
198
  function Diagram({ code }: { code: string }) {
166
199
  const { t } = useTranslation('agent-chat');
@@ -190,6 +223,7 @@ const components = {
190
223
  a({ href, children }: { href?: string; children?: ReactNode }) {
191
224
  return <MarkdownLink href={href}>{children}</MarkdownLink>;
192
225
  },
226
+ img: MarkdownImage,
193
227
  table({ children }: { children?: ReactNode }) {
194
228
  // A table wider than the column scrolls on its own instead of pushing the thread sideways.
195
229
  return (
@@ -210,7 +244,8 @@ const plainComponents = {
210
244
  </MarkdownCode>
211
245
  );
212
246
  },
213
- a: ExternalLink
247
+ a: ExternalLink,
248
+ img: PlainImage
214
249
  };
215
250
 
216
251
  // A reply sits under the heading of its message, an `h3`, so its own headings start one level below
package/src/host.ts CHANGED
@@ -313,6 +313,8 @@ export interface ChatHost {
313
313
  };
314
314
  /* The image a tool read, drawn under its row; null draws none. */
315
315
  ReadImage: ComponentType<{ path: string }> | null;
316
+ /* An image a reply's markdown names by a path on the host's machine, absolute or under the chat's cwd; left out, the `<img>` stays as written. */
317
+ MarkdownImage?: ComponentType<{ path: string; alt: string }>;
316
318
  code: {
317
319
  useMode(): 'light' | 'dark';
318
320
  /* The Shiki theme ids code is drawn in, one per mode. */