Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@markprompt/react

Package Overview
Dependencies
Maintainers
1
Versions
148
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@markprompt/react - npm Package Compare versions

Comparing version 0.43.0 to 0.44.0

dist/chat/ThreadSelect.d.ts

9

dist/chat/AssistantMessage.js
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/* eslint-disable @typescript-eslint/no-explicit-any */
import { DEFAULT_OPTIONS, isToolCalls } from '@markprompt/core';

@@ -32,7 +31,7 @@ import { useMemo } from 'react';

(chatOptions.showCopy || feedbackOptions?.enabled) &&
message.state === 'done' && (_jsx(Feedback, { message: message.content ?? '', variant: "icons", "data-show-feedback-always": showFeedbackAlways, className: "MarkpromptPromptFeedback", submitFeedback: (feedback, promptId) => {
submitFeedback(feedback, promptId);
feedbackOptions.onFeedbackSubmit?.(feedback, messages, promptId);
}, abortFeedbackRequest: abortFeedbackRequest, promptId: message.promptId, heading: feedbackOptions.heading, showFeedback: !!feedbackOptions?.enabled, showVotes: feedbackOptions.votes, showCopy: chatOptions.showCopy }))] })] }));
message.state === 'done' && (_jsx(Feedback, { message: message.content ?? '', variant: "icons", "data-show-feedback-always": showFeedbackAlways, className: "MarkpromptPromptFeedback", submitFeedback: (feedback, messageId) => {
submitFeedback(feedback, messageId);
feedbackOptions.onFeedbackSubmit?.(feedback, messages, messageId);
}, abortFeedbackRequest: abortFeedbackRequest, messageId: message.messageId, heading: feedbackOptions.heading, showFeedback: !!feedbackOptions?.enabled, showVotes: feedbackOptions.votes, showCopy: chatOptions.showCopy }))] })] }));
}
//# sourceMappingURL=AssistantMessage.js.map

@@ -5,5 +5,5 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

import { ChatViewForm } from './ChatViewForm.js';
import { ConversationSidebar } from './ConversationSidebar.js';
import { Messages } from './Messages.js';
import { useChatStore } from './store.js';
import { ThreadSidebar } from './ThreadSidebar.js';
import { DEFAULT_MARKPROMPT_OPTIONS } from '../constants.js';

@@ -25,3 +25,3 @@ import { ChevronLeftIcon } from '../icons.js';

const setDidAcceptDisclaimer = useChatStore((state) => state.setDidAcceptDisclaimer);
return (_jsxs("div", { className: "MarkpromptChatView", children: [_jsx(ConversationSidebar, { display: display }), _jsx("div", { className: "MarkpromptChatViewChatContainer", children: _jsxs("div", { className: "MarkpromptChatViewChat", children: [showBack ? (_jsx("div", { className: "MarkpromptChatViewNavigation", children: _jsx("button", { className: "MarkpromptGhostButton", onClick: onDidPressBack, children: _jsx(ChevronLeftIcon, { style: { width: 16, height: 16 }, strokeWidth: 2.5 }) }) })) : (
return (_jsxs("div", { className: "MarkpromptChatView", children: [_jsx(ThreadSidebar, { display: display }), _jsx("div", { className: "MarkpromptChatViewChatContainer", children: _jsxs("div", { className: "MarkpromptChatViewChat", children: [showBack ? (_jsx("div", { className: "MarkpromptChatViewNavigation", children: _jsx("button", { className: "MarkpromptGhostButton", onClick: onDidPressBack, children: _jsx(ChevronLeftIcon, { style: { width: 16, height: 16 }, strokeWidth: 2.5 }) }) })) : (
// Keep this for the grid template rows layout

@@ -28,0 +28,0 @@ _jsx("div", {})), !didAcceptDisclaimer && chatOptions?.disclaimerView ? (_jsx("div", { className: "MarkpromptDisclaimerView", children: _jsxs("div", { className: "MarkpromptDisclaimerViewMessage", children: [_jsx(RichText, { children: chatOptions.disclaimerView.message }), _jsx("button", { className: "MarkpromptButton", "data-variant": "primary", type: "submit", onClick: () => {

import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useContext, useEffect, useRef, useState, useMemo, } from 'react';
import { ConversationSelect } from './ConversationSelect.js';
import { ChatContext, useChatStore } from './store.js';
import { ThreadSelect } from './ThreadSelect.js';
import { LoadingIcon, SendIcon } from '../icons.js';

@@ -18,6 +18,2 @@ import * as BaseMarkprompt from '../primitives/headless.js';

const lastMessageState = useChatStore((state) => state.messages[state.messages.length - 1]?.state);
// const regenerateLastAnswer = useChatStore(
// (state) => state.regenerateLastAnswer,
// );
// const conversations = useChatStore(selectProjectConversations);
const formRef = useRef(null);

@@ -64,4 +60,4 @@ const textAreaRef = useRef(null);

formRef.current?.requestSubmit();
} }), chatOptions.history && (_jsx(ConversationSelect, { disabled: !didAcceptDisclaimer })), _jsx("div", {})] }) }));
} }), chatOptions.history && (_jsx(ThreadSelect, { disabled: !didAcceptDisclaimer })), _jsx("div", {})] }) }));
}
//# sourceMappingURL=ChatViewForm.js.map

@@ -16,3 +16,3 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

const messages = useChatStore((state) => state.messages);
const threadId = useChatStore((state) => state.conversationId);
const threadId = useChatStore((state) => state.threadId);
const submitChat = useChatStore((state) => state.submitChat);

@@ -19,0 +19,0 @@ const welcomeMessage = useMemo(() => {

@@ -10,3 +10,3 @@ import { type ChatCompletionMessageToolCall, type ChatCompletionTool, type SubmitChatOptions, type SubmitChatYield, type ChatCompletionChunk } from '@markprompt/core';

}
export interface ChatViewMessage extends Omit<SubmitChatYield, 'conversationId'> {
export interface ChatViewMessage extends Omit<SubmitChatYield, 'threadId'> {
/**

@@ -95,3 +95,3 @@ * Message id.

};
export interface ConversationData {
export interface ThreadData {
lastUpdated: string;

@@ -114,15 +114,15 @@ messages: ChatViewMessage[];

/**
* The current conversation id.
* The current thread id.
**/
conversationId?: string;
threadId?: string;
/**
* Set a conversation id.
* Set a thread id.
**/
setConversationId: (conversationId: string) => void;
setThreadId: (threadId: string) => void;
/**
* Select a conversation.
* Select a thread.
**/
selectConversation: (conversationId?: string) => void;
selectThread: (threadId?: string) => void;
/**
* The messages in the current conversation.
* The messages in the current thread.
**/

@@ -147,12 +147,12 @@ messages: ChatViewMessage[];

/**
* Dictionary of conversations by project id.
* Dictionary of threads by project id.
**/
conversationIdsByProjectKey: {
threadIdsByProjectKey: {
[projectKey: string]: string[];
};
/**
* Dictionary of messages by conversation id.
* Dictionary of messages by thread id.
**/
messagesByConversationId: {
[conversationId: string]: ConversationData;
messagesByThreadId: {
[threadId: string]: ThreadData;
};

@@ -209,3 +209,3 @@ /**

* Creates a chat store for a given project key.
* Keeps track of messages by project key and conversation id.
* Keeps track of messages by project key and thread id.
*

@@ -220,5 +220,5 @@ * @param projectKey - Markprompt project key

abort?: (() => void) | undefined;
conversationId?: string | undefined;
setConversationId: (conversationId: string) => void;
selectConversation: (conversationId?: string) => void;
threadId?: string | undefined;
setThreadId: (threadId: string) => void;
selectThread: (threadId?: string) => void;
messages: {

@@ -271,3 +271,3 @@ id: ReturnType<typeof crypto.randomUUID>;

}[] | undefined;
promptId?: string | undefined;
messageId?: string | undefined;
}[];

@@ -278,6 +278,6 @@ setMessages: (messages: ChatViewMessage[]) => void;

setToolCallById: (toolCallId: string, next: Partial<ToolCall>) => void;
conversationIdsByProjectKey: {
threadIdsByProjectKey: {
[x: string]: string[];
};
messagesByConversationId: {
messagesByThreadId: {
[x: string]: {

@@ -332,3 +332,3 @@ lastUpdated: string;

}[] | undefined;
promptId?: string | undefined;
messageId?: string | undefined;
}[];

@@ -347,11 +347,18 @@ };

options?: {
conversationId?: string | undefined;
conversationMetadata?: any;
debug?: boolean | undefined;
iDontKnowMessage?: string | undefined;
doNotInjectContext?: boolean | undefined;
allowFollowUpQuestions?: boolean | undefined;
excludeFromInsights?: boolean | undefined;
systemPrompt?: string | undefined;
context?: any;
model?: import("@markprompt/core").OpenAIModelId | undefined;
systemPrompt?: string | undefined;
policiesOptions?: {
enabled?: boolean | undefined;
useAll?: boolean | undefined;
ids?: string[] | undefined;
} | undefined;
retrievalOptions?: {
enabled?: boolean | undefined;
useAll?: boolean | undefined;
ids?: string[] | undefined;
} | undefined;
outputFormat?: "html" | "markdown" | "slack" | undefined;
jsonOutput?: boolean | undefined;
redact?: boolean | undefined;
temperature?: number | undefined;

@@ -364,4 +371,4 @@ topP?: number | undefined;

sectionsMatchThreshold?: number | undefined;
stream?: boolean | undefined;
tool_choice?: "none" | "auto" | {
threadId?: string | undefined;
toolChoice?: "none" | "auto" | {
function: {

@@ -372,4 +379,8 @@ name: string;

} | undefined;
outputFormat?: "slack" | "markdown" | undefined;
redact?: boolean | undefined;
doNotInjectContext?: boolean | undefined;
allowFollowUpQuestions?: boolean | undefined;
excludeFromInsights?: boolean | undefined;
debug?: boolean | undefined;
iDontKnowMessage?: string | undefined;
stream?: boolean | undefined;
tools?: {

@@ -445,5 +456,5 @@ tool: {

abort?: (() => void) | undefined;
conversationId?: string | undefined;
setConversationId: (conversationId: string) => void;
selectConversation: (conversationId?: string) => void;
threadId?: string | undefined;
setThreadId: (threadId: string) => void;
selectThread: (threadId?: string) => void;
messages: {

@@ -496,3 +507,3 @@ id: ReturnType<typeof crypto.randomUUID>;

}[] | undefined;
promptId?: string | undefined;
messageId?: string | undefined;
}[];

@@ -503,6 +514,6 @@ setMessages: (messages: ChatViewMessage[]) => void;

setToolCallById: (toolCallId: string, next: Partial<ToolCall>) => void;
conversationIdsByProjectKey: {
threadIdsByProjectKey: {
[x: string]: string[];
};
messagesByConversationId: {
messagesByThreadId: {
[x: string]: {

@@ -557,3 +568,3 @@ lastUpdated: string;

}[] | undefined;
promptId?: string | undefined;
messageId?: string | undefined;
}[];

@@ -572,11 +583,18 @@ };

options?: {
conversationId?: string | undefined;
conversationMetadata?: any;
debug?: boolean | undefined;
iDontKnowMessage?: string | undefined;
doNotInjectContext?: boolean | undefined;
allowFollowUpQuestions?: boolean | undefined;
excludeFromInsights?: boolean | undefined;
systemPrompt?: string | undefined;
context?: any;
model?: import("@markprompt/core").OpenAIModelId | undefined;
systemPrompt?: string | undefined;
policiesOptions?: {
enabled?: boolean | undefined;
useAll?: boolean | undefined;
ids?: string[] | undefined;
} | undefined;
retrievalOptions?: {
enabled?: boolean | undefined;
useAll?: boolean | undefined;
ids?: string[] | undefined;
} | undefined;
outputFormat?: "html" | "markdown" | "slack" | undefined;
jsonOutput?: boolean | undefined;
redact?: boolean | undefined;
temperature?: number | undefined;

@@ -589,4 +607,4 @@ topP?: number | undefined;

sectionsMatchThreshold?: number | undefined;
stream?: boolean | undefined;
tool_choice?: "none" | "auto" | {
threadId?: string | undefined;
toolChoice?: "none" | "auto" | {
function: {

@@ -597,4 +615,8 @@ name: string;

} | undefined;
outputFormat?: "slack" | "markdown" | undefined;
redact?: boolean | undefined;
doNotInjectContext?: boolean | undefined;
allowFollowUpQuestions?: boolean | undefined;
excludeFromInsights?: boolean | undefined;
debug?: boolean | undefined;
iDontKnowMessage?: string | undefined;
stream?: boolean | undefined;
tools?: {

@@ -666,3 +688,3 @@ tool: {

interface ChatProviderProps {
chatOptions: MarkpromptOptions['chat'];
chatOptions?: MarkpromptOptions['chat'];
children: ReactNode;

@@ -675,4 +697,4 @@ debug?: boolean;

export declare function useChatStore<T>(selector: (state: ChatStoreState) => T): T;
export declare const selectProjectConversations: (state: ChatStoreState) => [
conversationId: string,
export declare const selectProjectThreads: (state: ChatStoreState) => [
threadId: string,
{

@@ -679,0 +701,0 @@ lastUpdated: string;

import { jsx as _jsx } from "react/jsx-runtime";
import { isAbortError, isToolCall, isToolCalls, submitChat, } from '@markprompt/core';
import { isAbortError, isToolCall, submitChat, } from '@markprompt/core';
import { createContext, useContext, useEffect, useRef, } from 'react';

@@ -7,60 +7,7 @@ import { createStore, useStore } from 'zustand';

import { immer } from 'zustand/middleware/immer';
import { toValidApiMessages } from './utils.js';
import { hasValueAtKey, isIterable, isPresent, isStoredError, } from '../utils.js';
function toApiMessages(messages) {
return (messages
.map(({ content, role, tool_calls, tool_call_id, name }) => {
if (!content && !tool_calls) {
// Ignore empty messages unless it's a tool_call
return undefined;
}
switch (role) {
case 'assistant': {
const msg = {
content: content ?? null,
role,
};
if (isToolCalls(tool_calls)) {
msg.tool_calls = tool_calls;
}
return msg;
}
// case 'system': {
// return {
// content: content ?? null,
// role,
// } satisfies ChatCompletionSystemMessageParam;
// }
case 'tool': {
if (!tool_call_id)
throw new Error('tool_call_id is required');
if (!content)
throw new Error('content is required');
return {
content,
role,
tool_call_id,
};
}
case 'user': {
if (!content)
throw new Error('content is required');
return {
content,
role,
...(name ? { name } : {}),
};
}
}
})
.filter(isPresent)
// remove the last message if role is assistant and content is null
// we add this message locally as a placeholder for ourself and OpenAI errors out
// if we send it to them
.filter((m, i, arr) => !(i === arr.length - 1 &&
m.role === 'assistant' &&
m.content === null)));
}
/**
* Creates a chat store for a given project key.
* Keeps track of messages by project key and conversation id.
* Keeps track of messages by project key and thread id.
*

@@ -70,4 +17,3 @@ * @param projectKey - Markprompt project key

*/
export const createChatStore = ({ chatOptions, debug, persistChatHistory, projectKey, apiUrl,
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export const createChatStore = ({ chatOptions, debug, persistChatHistory, projectKey, apiUrl, // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
}) => {

@@ -82,26 +28,26 @@ if (!projectKey) {

didAcceptDisclaimer: false,
conversationIdsByProjectKey: {
threadIdsByProjectKey: {
[projectKey]: [],
},
messagesByConversationId: {},
messagesByThreadId: {},
toolCallsByToolCallId: {},
didAcceptDisclaimerByProjectKey: {},
setConversationId: (conversationId) => {
setThreadId: (threadId) => {
set((state) => {
// set the conversation id for this session
state.conversationIdsByProjectKey[projectKey] ??= [];
state.conversationId = conversationId;
if (!isIterable(state.conversationIdsByProjectKey[projectKey])) {
// Set the thread id for this session
state.threadIdsByProjectKey[projectKey] ??= [];
state.threadId = threadId;
if (!isIterable(state.threadIdsByProjectKey[projectKey])) {
// Backward-compatibility
state.conversationIdsByProjectKey[projectKey] = [];
state.threadIdsByProjectKey[projectKey] = [];
}
// save the conversation id for this project, for later sessions
state.conversationIdsByProjectKey[projectKey] = [
// Save the thread id for this project, for later sessions
state.threadIdsByProjectKey[projectKey] = [
...new Set([
...state.conversationIdsByProjectKey[projectKey],
conversationId,
...state.threadIdsByProjectKey[projectKey],
threadId,
]),
];
// save the messages for this conversation
state.messagesByConversationId[conversationId] = {
// Save the messages for this thread
state.messagesByThreadId[threadId] = {
lastUpdated: new Date().toISOString(),

@@ -112,4 +58,4 @@ messages: state.messages,

},
selectConversation: (conversationId) => {
if (conversationId && conversationId === get().conversationId) {
selectThread: (threadId) => {
if (threadId && threadId === get().threadId) {
return;

@@ -120,12 +66,12 @@ }

set((state) => {
if (!conversationId) {
// start a new conversation
state.conversationId = undefined;
if (!threadId) {
// Start a new thread
state.threadId = undefined;
state.messages = [];
return;
}
// restore an existing conversation
state.conversationId = conversationId;
// Restore an existing thread
state.threadId = threadId;
state.messages =
state.messagesByConversationId[conversationId]?.messages ?? [];
state.messagesByThreadId[threadId]?.messages ?? [];
});

@@ -136,7 +82,7 @@ },

state.messages = messages;
const conversationId = state.conversationId;
if (!conversationId)
const threadId = state.threadId;
if (!threadId)
return;
// save the message to local storage
state.messagesByConversationId[conversationId] = {
state.messagesByThreadId[threadId] = {
lastUpdated: new Date().toISOString(),

@@ -153,7 +99,7 @@ messages,

state.messages[index] = currentMessage;
const conversationId = state.conversationId;
if (!conversationId)
const threadId = state.threadId;
if (!threadId)
return;
// save the message to local storage
state.messagesByConversationId[conversationId] = {
state.messagesByThreadId[threadId] = {
lastUpdated: new Date().toISOString(),

@@ -174,7 +120,7 @@ messages: state.messages,

state.messages[index] = currentMessage;
const conversationId = state.conversationId;
if (!conversationId)
const threadId = state.threadId;
if (!threadId)
return;
// save the message to local storage
state.messagesByConversationId[conversationId] = {
state.messagesByThreadId[threadId] = {
lastUpdated: new Date().toISOString(),

@@ -235,3 +181,3 @@ messages: state.messages,

// Get ready to do the request
const apiMessages = toApiMessages(get().messages);
const apiMessages = toValidApiMessages(get().messages);
for (const id of [...messageIds, responseId]) {

@@ -244,3 +190,3 @@ get().setMessageById(id, {

apiUrl: get().apiUrl,
conversationId: get().conversationId,
threadId: get().threadId,
signal: controller.signal,

@@ -256,4 +202,4 @@ debug,

continue;
if (chunk.conversationId) {
get().setConversationId(chunk.conversationId);
if (chunk.threadId) {
get().setThreadId(chunk.threadId);
}

@@ -423,7 +369,7 @@ for (const id of messageIds) {

}),
// only store conversationsByProjectKey in local storage
// Only store threadsByProjectKey in local storage
partialize: (state) => {
return {
conversationIdsByProjectKey: state.conversationIdsByProjectKey,
messagesByConversationId: state.messagesByConversationId,
threadIdsByProjectKey: state.threadIdsByProjectKey,
messagesByThreadId: state.messagesByThreadId,
toolCallsByToolCallId: state.toolCallsByToolCallId,

@@ -433,3 +379,3 @@ didAcceptDisclaimerByProjectKey: state.didAcceptDisclaimerByProjectKey,

},
// restore the last conversation for this project if it's < 4 hours old
// Restore the last tjread for this project if it's < 4 hours old
onRehydrateStorage: () => (state) => {

@@ -443,10 +389,11 @@ if (!state || typeof state !== 'object')

}
const { conversationIdsByProjectKey, messagesByConversationId } = state;
const conversationIds = conversationIdsByProjectKey?.[projectKey] ?? [];
const { threadIdsByProjectKey, messagesByThreadId } = state;
const threadIds = threadIdsByProjectKey?.[projectKey] ?? [];
const now = new Date();
const fourHoursAgo = new Date(now.getTime() - 4 * 60 * 60 * 1000);
const projectConversations = Object.entries(messagesByConversationId)
// filter out conversations that are not in the list of conversations for this project
.filter(([id]) => conversationIds.includes(id))
// filter out conversations older than 4 hours
const projectThreads = Object.entries(messagesByThreadId)
// Filter out threads that are not in the list of threads for
// this project
.filter(([id]) => threadIds.includes(id))
// Filter out threads older than 4 hours
.filter(([, { lastUpdated }]) => {

@@ -458,8 +405,7 @@ const lastUpdatedDate = new Date(lastUpdated);

.sort(([, { lastUpdated: a }], [, { lastUpdated: b }]) => b.localeCompare(a));
if (projectConversations.length === 0 ||
!isPresent(projectConversations[0])) {
if (projectThreads.length === 0 || !isPresent(projectThreads[0])) {
return;
}
const [conversationId, { messages }] = projectConversations[0];
state.setConversationId(conversationId);
const [threadId, { messages }] = projectThreads[0];
state.setThreadId(threadId);
state.setMessages(messages.map((x) => ({

@@ -503,15 +449,16 @@ ...x,

}
export const selectProjectConversations = (state) => {
export const selectProjectThreads = (state) => {
const projectKey = state.projectKey;
const conversationIds = state.conversationIdsByProjectKey[projectKey];
if (!conversationIds || conversationIds.length === 0)
const threadIds = state.threadIdsByProjectKey[projectKey];
if (!threadIds || threadIds.length === 0)
return [];
const messagesByConversationId = Object.entries(state.messagesByConversationId)
.filter(([id]) => conversationIds.includes(id))
// ascending order, so the newest conversation will be closest to the dropdown toggle
const messagesByThreadId = Object.entries(state.messagesByThreadId)
.filter(([id]) => threadIds.includes(id))
// Ascending order, so the newest thread will be closest to the
// dropdown toggle
.sort(([, { lastUpdated: a }], [, { lastUpdated: b }]) => a.localeCompare(b));
if (!messagesByConversationId)
if (!messagesByThreadId)
return [];
return messagesByConversationId;
return messagesByThreadId;
};
//# sourceMappingURL=store.js.map
import { type ChatCompletionMessageParam } from '@markprompt/core';
import type { ChatViewMessage } from './store.js';
export declare function toApiMessages(messages: (ChatViewMessage & {
export declare function toValidApiMessages(messages: (ChatViewMessage & {
tool_call_id?: string;
})[]): ChatCompletionMessageParam[];
//# sourceMappingURL=utils.d.ts.map
import { isToolCalls, } from '@markprompt/core';
import { isPresent } from '../utils.js';
export function toApiMessages(messages) {
export function toValidApiMessages(messages) {
return (messages
.map(({ content, role, tool_calls, tool_call_id, name }) => {
if (!content) {
// Ignore empty messages
return undefined;
}
.map(({ content, role, tool_calls, tool_call_id, name }, i) => {
switch (role) {
case 'assistant': {
const msg = {
content: content ?? null,
content: content ?? '',
role,
};
if (isToolCalls(tool_calls))
if (isToolCalls(tool_calls)) {
msg.tool_calls = tool_calls;
// If this is a tool_calls assistant message and the next
// message is not a tool message, ignore it, as it will
// result in an invalid API request.
const nextMessage = messages[i + 1];
if (nextMessage && nextMessage.role !== 'tool') {
return undefined;
}
}
return msg;

@@ -24,3 +28,3 @@ }

return {
content: content ?? null,
content: content ?? '',
role,

@@ -32,3 +36,3 @@ tool_call_id,

return {
content: content ?? null,
content: content ?? '',
role,

@@ -41,9 +45,10 @@ ...(name ? { name } : {}),

.filter(isPresent)
// remove the last message if role is assistant and content is null
// we add this message locally as a placeholder for ourself and OpenAI errors out
// if we send it to them
// Remove the last message if role is assistant and content is null
// and is not a tool call. We add this message locally as a placeholder
// for ourselves, and our API will error if we send it.
.filter((m, i, arr) => !(i === arr.length - 1 &&
m.role === 'assistant' &&
isToolCalls(m.tool_calls) &&
m.content === null)));
}
//# sourceMappingURL=utils.js.map

@@ -6,3 +6,3 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";

import { useId, useMemo, useRef, useState } from 'react';
import { toApiMessages } from './chat/utils.js';
import { toValidApiMessages } from './chat/utils.js';
import { ChevronDownIcon, ChevronLeftIcon, LoadingIcon } from './icons.js';

@@ -15,8 +15,6 @@ import { useChatStore, } from './index.js';

const projectKey = useGlobalStore((state) => state.options.projectKey);
const conversationId = useChatStore((state) => state.conversationId);
const threadId = useChatStore((state) => state.threadId);
const provider = useGlobalStore((state) => state.options.integrations?.createTicket?.provider);
const apiUrl = useGlobalStore((state) => state.options?.apiUrl);
const summary = useGlobalStore((state) => conversationId
? state.tickets?.summaryByConversationId[conversationId]
: undefined);
const summary = useGlobalStore((state) => threadId ? state.tickets?.summaryByThreadId[threadId] : undefined);
const messages = useChatStore((state) => state.messages);

@@ -74,3 +72,3 @@ const [totalFileSize, setTotalFileSize] = useState(0);

}
const transcript = toApiMessages(messages)
const transcript = toValidApiMessages(messages)
.map((m) => {

@@ -77,0 +75,0 @@ return `${m.role === 'user' ? 'Me' : 'AI'}: ${m.content}`;

@@ -9,3 +9,3 @@ import { type ReactElement, type ComponentPropsWithoutRef } from 'react';

variant: 'text' | 'icons';
promptId?: string;
messageId?: string;
showFeedback?: boolean;

@@ -12,0 +12,0 @@ showVotes?: boolean;

@@ -11,6 +11,6 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";

export function Feedback(props) {
const { message, heading = DEFAULT_MARKPROMPT_OPTIONS.feedback.heading, submitFeedback, abortFeedbackRequest, variant, promptId, showFeedback = true, showVotes = true, showCopy, ...divProps } = props;
const { message, heading = DEFAULT_MARKPROMPT_OPTIONS.feedback.heading, submitFeedback, abortFeedbackRequest, variant, messageId, showFeedback = true, showVotes = true, showCopy, ...divProps } = props;
const [feedback, setFeedback] = useState();
function handleFeedback(feedback) {
submitFeedback(feedback, promptId);
submitFeedback(feedback, messageId);
setFeedback(feedback);

@@ -17,0 +17,0 @@ }

@@ -15,3 +15,3 @@ import { type PromptFeedback, type SubmitFeedbackOptions } from '@markprompt/core';

/** Submit feedback for the current message */
submitFeedback: (feedback: PromptFeedback, promptId?: string) => void;
submitFeedback: (feedback: PromptFeedback, messageId?: string) => void;
/** Submit CSAT for a thread */

@@ -18,0 +18,0 @@ submitThreadCSAT: (threadId: string, csat: CSAT) => void;

@@ -9,10 +9,10 @@ import { submitFeedback as submitFeedbackCore, submitCSAT as submitCSATCore, } from '@markprompt/core';

const { ref: controllerRef, abort } = useAbortController();
const submitFeedback = useCallback(async (feedback, promptId) => {
const submitFeedback = useCallback(async (feedback, messageId) => {
abort();
// we need to be able to associate the feedback to a prompt
if (!promptId)
if (!messageId)
return;
const controller = new AbortController();
controllerRef.current = controller;
const promise = submitFeedbackCore({ feedback, promptId }, projectKey, {
const promise = submitFeedbackCore({ feedback, messageId }, projectKey, {
...feedbackOptions,

@@ -19,0 +19,0 @@ signal: controller.signal,

@@ -13,6 +13,6 @@ import { type ReactNode } from 'react';

tickets?: {
summaryByConversationId: {
[conversationId: string]: ChatViewMessage;
summaryByThreadId: {
[threadId: string]: ChatViewMessage;
};
createTicketSummary: (conversationId: string, messages: ChatViewMessage[]) => void;
createTicketSummary: (threadId: string, messages: ChatViewMessage[]) => void;
};

@@ -19,0 +19,0 @@ }

@@ -6,3 +6,3 @@ import { jsx as _jsx } from "react/jsx-runtime";

import { immer } from 'zustand/middleware/immer';
import { toApiMessages } from './chat/utils.js';
import { toValidApiMessages } from './chat/utils.js';
import { getDefaultView } from './utils.js';

@@ -35,7 +35,7 @@ function getInitialView(options) {

tickets: {
summaryByConversationId: {},
createTicketSummary: async (conversationId, messages) => {
summaryByThreadId: {},
createTicketSummary: async (threadId, messages) => {
const summaryId = crypto.randomUUID();
set((state) => {
state.tickets.summaryByConversationId[conversationId] = {
state.tickets.summaryByThreadId[threadId] = {
id: summaryId,

@@ -47,3 +47,3 @@ references: [],

const options = {
conversationId: conversationId,
threadId: threadId,
...get().options.chat,

@@ -58,3 +58,3 @@ apiUrl: get().options.apiUrl,

};
const conversation = toApiMessages(messages)
const conversation = toValidApiMessages(messages)
.map((m) => {

@@ -71,4 +71,3 @@ return `${m.role === 'user' ? 'User' : 'AI'}:\n\n${m.content}`;

set((state) => {
state.tickets.summaryByConversationId[conversationId].state =
'preload';
state.tickets.summaryByThreadId[threadId].state = 'preload';
});

@@ -78,4 +77,4 @@ try {

set((state) => {
state.tickets.summaryByConversationId[conversationId] = {
...state.tickets.summaryByConversationId[conversationId],
state.tickets.summaryByThreadId[threadId] = {
...state.tickets.summaryByThreadId[threadId],
state: 'streaming-answer',

@@ -89,4 +88,4 @@ ...chunk,

set((state) => {
state.tickets.summaryByConversationId[conversationId] = {
...state.tickets.summaryByConversationId[conversationId],
state.tickets.summaryByThreadId[threadId] = {
...state.tickets.summaryByThreadId[threadId],
state: 'cancelled',

@@ -102,4 +101,3 @@ };

set((state) => {
state.tickets.summaryByConversationId[conversationId].state =
'done';
state.tickets.summaryByThreadId[threadId].state = 'done';
});

@@ -106,0 +104,0 @@ },

@@ -15,10 +15,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";

const [isCreatingTicketSummary, setIsCreatingTicketSummary] = useState(false);
const conversationId = useChatStore((state) => state.conversationId);
const threadId = useChatStore((state) => state.threadId);
const messages = useChatStore((state) => state.messages);
const selectConversation = useChatStore((state) => state.selectConversation);
const selectThread = useChatStore((state) => state.selectThread);
const createTicketSummary = useGlobalStore((state) => state.tickets?.createTicketSummary);
useEffect(() => {
// Clear past conversations
selectConversation(undefined);
}, [selectConversation]);
// Clear past thread
selectThread(undefined);
}, [selectThread]);
const placeholder = useMemo(() => {

@@ -43,3 +43,3 @@ const _placeholder = integrations?.createTicket?.chat?.placeholder;

}
if (!messages || messages.length === 0 || !conversationId) {
if (!messages || messages.length === 0 || !threadId) {
setView('ticket');

@@ -49,7 +49,7 @@ return;

setIsCreatingTicketSummary(true);
await createTicketSummary?.(conversationId, messages);
await createTicketSummary?.(threadId, messages);
setIsCreatingTicketSummary(false);
setView('ticket');
}, [
conversationId,
threadId,
createTicketSummary,

@@ -56,0 +56,0 @@ integrations?.createTicket?.enabled,

@@ -133,3 +133,3 @@ import { type AlgoliaDocSearchHit, type FileSectionReference, type PromptFeedback, type SearchResult, type SubmitFeedbackOptions, type SubmitSearchQueryOptions } from '@markprompt/core';

*/
onFeedbackSubmit?: (feedback: PromptFeedback, messages: ChatViewMessage[], promptId?: string) => void;
onFeedbackSubmit?: (feedback: PromptFeedback, messages: ChatViewMessage[], messageId?: string) => void;
}

@@ -136,0 +136,0 @@ export interface AvatarsOptions {

{
"name": "@markprompt/react",
"version": "0.43.0",
"version": "0.44.0",
"description": "A headless React component for adding GPT-4 powered search using the Markprompt API.",

@@ -26,3 +26,3 @@ "repository": {

"@floating-ui/react-dom": "^2.0.8",
"@markprompt/core": "^0.27.0",
"@markprompt/core": "^0.28.0",
"@radix-ui/react-accessible-icon": "^1.0.3",

@@ -29,0 +29,0 @@ "@radix-ui/react-dialog": "^1.0.5",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc