diff --git a/app/components/chat/Artifact.tsx b/app/components/chat/Artifact.tsx
index 5f0c9910..230ed3c2 100644
--- a/app/components/chat/Artifact.tsx
+++ b/app/components/chat/Artifact.tsx
@@ -23,15 +23,16 @@ if (import.meta.hot) {
interface ArtifactProps {
messageId: string;
+ artifactId: string;
}
-export const Artifact = memo(({ messageId }: ArtifactProps) => {
+export const Artifact = memo(({ artifactId }: ArtifactProps) => {
const userToggledActions = useRef(false);
const [showActions, setShowActions] = useState(false);
const [allActionFinished, setAllActionFinished] = useState(false);
const artifacts = useStore(workbenchStore.artifacts);
- const artifact = artifacts[messageId];
+ const artifact = artifacts[artifactId];
const actions = useStore(
computed(artifact.runner.actions, (actions) => {
diff --git a/app/components/chat/Markdown.tsx b/app/components/chat/Markdown.tsx
index 90ba6b7f..bfc8a458 100644
--- a/app/components/chat/Markdown.tsx
+++ b/app/components/chat/Markdown.tsx
@@ -25,12 +25,17 @@ export const Markdown = memo(({ children, html = false, limitedMarkdown = false
div: ({ className, children, node, ...props }) => {
if (className?.includes('__boltArtifact__')) {
const messageId = node?.properties.dataMessageId as string;
+ const artifactId = node?.properties.dataArtifactId as string;
if (!messageId) {
logger.error(`Invalid message id ${messageId}`);
}
- return ;
+ if (!artifactId) {
+ logger.error(`Invalid artifact id ${artifactId}`);
+ }
+
+ return ;
}
if (className?.includes('__boltThought__')) {
diff --git a/app/lib/runtime/message-parser.ts b/app/lib/runtime/message-parser.ts
index 3b41b6d6..94017f20 100644
--- a/app/lib/runtime/message-parser.ts
+++ b/app/lib/runtime/message-parser.ts
@@ -12,6 +12,7 @@ const logger = createScopedLogger('MessageParser');
export interface ArtifactCallbackData extends BoltArtifactData {
messageId: string;
+ artifactId: string;
}
export interface ActionCallbackData {
@@ -34,6 +35,7 @@ export interface ParserCallbacks {
interface ElementFactoryProps {
messageId: string;
+ artifactId: string;
}
type ElementFactory = (props: ElementFactoryProps) => string;
@@ -47,6 +49,7 @@ interface MessageState {
position: number;
insideArtifact: boolean;
insideAction: boolean;
+ artifactCounter: number;
currentArtifact?: BoltArtifactData;
currentAction: BoltActionData;
actionId: number;
@@ -81,6 +84,7 @@ export class StreamingMessageParser {
position: 0,
insideAction: false,
insideArtifact: false,
+ artifactCounter: 0,
currentAction: { content: '' },
actionId: 0,
};
@@ -187,7 +191,11 @@ export class StreamingMessageParser {
break;
}
} else if (artifactCloseIndex !== -1) {
- this._options.callbacks?.onArtifactClose?.({ messageId, ...currentArtifact });
+ this._options.callbacks?.onArtifactClose?.({
+ messageId,
+ artifactId: currentArtifact.id,
+ ...currentArtifact,
+ });
state.insideArtifact = false;
state.currentArtifact = undefined;
@@ -220,7 +228,9 @@ export class StreamingMessageParser {
const artifactTitle = this.#extractAttribute(artifactTag, 'title') as string;
const type = this.#extractAttribute(artifactTag, 'type') as string;
- const artifactId = this.#extractAttribute(artifactTag, 'id') as string;
+
+ // const artifactId = this.#extractAttribute(artifactTag, 'id') as string;
+ const artifactId = `${messageId}-${state.artifactCounter++}`;
if (!artifactTitle) {
logger.warn('Artifact title missing');
@@ -240,11 +250,15 @@ export class StreamingMessageParser {
state.currentArtifact = currentArtifact;
- this._options.callbacks?.onArtifactOpen?.({ messageId, ...currentArtifact });
+ this._options.callbacks?.onArtifactOpen?.({
+ messageId,
+ artifactId: currentArtifact.id,
+ ...currentArtifact,
+ });
const artifactFactory = this._options.artifactElement ?? createArtifactElement;
- output += artifactFactory({ messageId });
+ output += artifactFactory({ messageId, artifactId });
i = openTagEnd + 1;
} else {
diff --git a/app/lib/stores/workbench.ts b/app/lib/stores/workbench.ts
index 4914ebc5..bd1572af 100644
--- a/app/lib/stores/workbench.ts
+++ b/app/lib/stores/workbench.ts
@@ -255,17 +255,17 @@ export class WorkbenchStore {
}
addArtifact({ messageId, title, id, type }: ArtifactCallbackData) {
- const artifact = this.#getArtifact(messageId);
+ const artifact = this.#getArtifact(id);
if (artifact) {
return;
}
- if (!this.artifactIdList.includes(messageId)) {
- this.artifactIdList.push(messageId);
+ if (!this.artifactIdList.includes(id)) {
+ this.artifactIdList.push(id);
}
- this.artifacts.setKey(messageId, {
+ this.artifacts.setKey(id, {
id,
title,
closed: false,
@@ -284,14 +284,14 @@ export class WorkbenchStore {
});
}
- updateArtifact({ messageId }: ArtifactCallbackData, state: Partial) {
- const artifact = this.#getArtifact(messageId);
+ updateArtifact({ artifactId }: ArtifactCallbackData, state: Partial) {
+ const artifact = this.#getArtifact(artifactId);
if (!artifact) {
return;
}
- this.artifacts.setKey(messageId, { ...artifact, ...state });
+ this.artifacts.setKey(artifactId, { ...artifact, ...state });
}
addAction(data: ActionCallbackData) {
// this._addAction(data);
@@ -299,9 +299,9 @@ export class WorkbenchStore {
this.addToExecutionQueue(() => this._addAction(data));
}
async _addAction(data: ActionCallbackData) {
- const { messageId } = data;
+ const { artifactId } = data;
- const artifact = this.#getArtifact(messageId);
+ const artifact = this.#getArtifact(artifactId);
if (!artifact) {
unreachable('Artifact not found');
@@ -318,9 +318,9 @@ export class WorkbenchStore {
}
}
async _runAction(data: ActionCallbackData, isStreaming: boolean = false) {
- const { messageId } = data;
+ const { artifactId } = data;
- const artifact = this.#getArtifact(messageId);
+ const artifact = this.#getArtifact(artifactId);
if (!artifact) {
unreachable('Artifact not found');