@meistrari/chat-nuxt 1.9.0 → 1.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/README.md +1 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/MeistrariChatEmbed.vue +3 -0
- package/dist/runtime/components/chat/conversation-creator-filter.d.vue.ts +3 -0
- package/dist/runtime/components/chat/conversation-creator-filter.vue +95 -0
- package/dist/runtime/components/chat/conversation-creator-filter.vue.d.ts +3 -0
- package/dist/runtime/components/chat/conversation-item.d.vue.ts +1 -0
- package/dist/runtime/components/chat/conversation-item.vue +44 -5
- package/dist/runtime/components/chat/conversation-item.vue.d.ts +1 -0
- package/dist/runtime/components/chat/conversation-list.d.vue.ts +2 -0
- package/dist/runtime/components/chat/conversation-list.vue +19 -6
- package/dist/runtime/components/chat/conversation-list.vue.d.ts +2 -0
- package/dist/runtime/components/chat/conversation-search.vue +21 -2
- package/dist/runtime/components/chat/mobile/shell/drawer.vue +1 -0
- package/dist/runtime/components/chat/mobile/shell/shell.d.vue.ts +2 -2
- package/dist/runtime/components/chat/mobile/shell/shell.vue.d.ts +2 -2
- package/dist/runtime/composables/useConversations.d.ts +2 -0
- package/dist/runtime/composables/useConversations.js +250 -110
- package/dist/runtime/composables/useEmbedConfig.d.ts +3 -0
- package/dist/runtime/composables/useEmbedConfig.js +4 -0
- package/dist/runtime/embed/components/ChatEmbed.vue +2 -0
- package/dist/runtime/embed/components/ChatEmbedInner.vue +10 -39
- package/dist/runtime/server/api/chat/conversations/metadata.get.d.ts +1 -0
- package/dist/runtime/server/api/chat/conversations/metadata.get.js +1 -0
- package/dist/runtime/server/api/conversations/index.get.js +5 -4
- package/dist/runtime/server/api/conversations/metadata.get.d.ts +2 -0
- package/dist/runtime/server/api/conversations/metadata.get.js +20 -0
- package/dist/runtime/server/utils/conversation-list.d.ts +4 -0
- package/dist/runtime/server/utils/conversation-list.js +28 -0
- package/dist/runtime/types/chat.d.ts +12 -0
- package/dist/runtime/types/chat.js +4 -0
- package/dist/runtime/types/embed.d.ts +3 -0
- package/dist/runtime/utils/conversation-creator-filter.d.ts +5 -0
- package/dist/runtime/utils/conversation-creator-filter.js +24 -0
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { defineEventHandler } from "h3";
|
|
1
|
+
import { defineEventHandler, getQuery } from "h3";
|
|
2
2
|
import { desc } from "drizzle-orm";
|
|
3
3
|
import { useDb, schema } from "#chat-runtime/server/db";
|
|
4
4
|
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
5
|
-
import {
|
|
5
|
+
import { conversationListConditions, resolveRequestedConversationCreatorFilter } from "#chat-runtime/server/utils/conversation-list";
|
|
6
6
|
import { logger } from "#chat-runtime/server/utils/logger";
|
|
7
7
|
export default defineEventHandler(async (event) => {
|
|
8
8
|
const context = resolveChatRuntimeContext(event);
|
|
9
|
+
const creatorFilter = resolveRequestedConversationCreatorFilter(getQuery(event).creator);
|
|
9
10
|
const db = useDb();
|
|
10
|
-
const conversations = await db.select().from(schema.conversations).where(
|
|
11
|
-
logger.debug({ workspaceId: context.workspaceId, count: conversations.length }, "Conversations listed");
|
|
11
|
+
const conversations = await db.select().from(schema.conversations).where(conversationListConditions(context, creatorFilter)).orderBy(desc(schema.conversations.updatedAt));
|
|
12
|
+
logger.debug({ workspaceId: context.workspaceId, creatorFilter, count: conversations.length }, "Conversations listed");
|
|
12
13
|
return conversations;
|
|
13
14
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineEventHandler } from "h3";
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
import { useDb, schema } from "#chat-runtime/server/db";
|
|
4
|
+
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
5
|
+
import { conversationScopeConditions } from "#chat-runtime/server/utils/conversation-scope";
|
|
6
|
+
import { logger } from "#chat-runtime/server/utils/logger";
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const context = resolveChatRuntimeContext(event);
|
|
9
|
+
const db = useDb();
|
|
10
|
+
const [metadata] = await db.select({
|
|
11
|
+
all: sql`COUNT(*)::int`,
|
|
12
|
+
mine: sql`COUNT(*) FILTER (WHERE ${schema.conversations.userId} = ${context.user.id})::int`
|
|
13
|
+
}).from(schema.conversations).where(conversationScopeConditions(context));
|
|
14
|
+
const counts = {
|
|
15
|
+
all: metadata?.all ?? 0,
|
|
16
|
+
mine: metadata?.mine ?? 0
|
|
17
|
+
};
|
|
18
|
+
logger.debug({ workspaceId: context.workspaceId, counts }, "Conversations metadata loaded");
|
|
19
|
+
return { counts };
|
|
20
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ChatRuntimeContext } from '#chat-runtime/server/utils/chat-context';
|
|
2
|
+
import type { ConversationCreatorFilter } from '#chat-runtime/types/chat';
|
|
3
|
+
export declare function resolveRequestedConversationCreatorFilter(requestedCreator: unknown): ConversationCreatorFilter;
|
|
4
|
+
export declare function conversationListConditions(context: ChatRuntimeContext, creatorFilter?: ConversationCreatorFilter): import("drizzle-orm").SQL<unknown> | undefined;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { and, eq } from "drizzle-orm";
|
|
2
|
+
import { createError } from "h3";
|
|
3
|
+
import { schema } from "#chat-runtime/server/db";
|
|
4
|
+
import { conversationScopeConditions } from "#chat-runtime/server/utils/conversation-scope";
|
|
5
|
+
export function resolveRequestedConversationCreatorFilter(requestedCreator) {
|
|
6
|
+
if (Array.isArray(requestedCreator)) {
|
|
7
|
+
throw createError({
|
|
8
|
+
statusCode: 400,
|
|
9
|
+
statusMessage: "Invalid conversation creator filter"
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
if (requestedCreator === void 0 || requestedCreator === null || requestedCreator === "" || requestedCreator === "all") {
|
|
13
|
+
return "all";
|
|
14
|
+
}
|
|
15
|
+
if (requestedCreator === "me") {
|
|
16
|
+
return "mine";
|
|
17
|
+
}
|
|
18
|
+
throw createError({
|
|
19
|
+
statusCode: 400,
|
|
20
|
+
statusMessage: "Invalid conversation creator filter"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function conversationListConditions(context, creatorFilter = "all") {
|
|
24
|
+
return and(
|
|
25
|
+
conversationScopeConditions(context),
|
|
26
|
+
creatorFilter === "mine" ? eq(schema.conversations.userId, context.user.id) : void 0
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -5,6 +5,18 @@ export type ExternalSkill = SchemaExternalSkill;
|
|
|
5
5
|
export type MessageFile = SchemaMessageFile;
|
|
6
6
|
export type Conversation = InferSelectModel<typeof conversations>;
|
|
7
7
|
export type Message = InferSelectModel<typeof messages>;
|
|
8
|
+
export type ConversationCreatorFilter = 'all' | 'mine';
|
|
9
|
+
export type ConversationCreatorFilterCounts = Record<ConversationCreatorFilter, number>;
|
|
10
|
+
export type ConversationListMetadata = {
|
|
11
|
+
counts: ConversationCreatorFilterCounts;
|
|
12
|
+
};
|
|
13
|
+
export declare const CONVERSATION_CREATOR_FILTER_OPTIONS: readonly [{
|
|
14
|
+
readonly label: "Todas";
|
|
15
|
+
readonly value: "all";
|
|
16
|
+
}, {
|
|
17
|
+
readonly label: "Minhas";
|
|
18
|
+
readonly value: "mine";
|
|
19
|
+
}];
|
|
8
20
|
export type ConversationWithMessages = Conversation & {
|
|
9
21
|
messages: Message[];
|
|
10
22
|
};
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export const CONVERSATION_CREATOR_FILTER_OPTIONS = [
|
|
2
|
+
{ label: "Todas", value: "all" },
|
|
3
|
+
{ label: "Minhas", value: "mine" }
|
|
4
|
+
];
|
|
1
5
|
export const AVAILABLE_MODELS = [
|
|
2
6
|
{ value: "claude-sonnet-4-5", label: "Sonnet 4.5", description: "High performant agent for complex tasks" },
|
|
3
7
|
{ value: "claude-sonnet-4-6", label: "Sonnet 4.6", description: "Fast and intelligent agent" },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Component, DeepReadonly } from 'vue';
|
|
2
2
|
import type { WorkspaceSettings } from './workspace-settings-data.js';
|
|
3
3
|
import type { TelaAgentExecutionInput } from './tela-agent.js';
|
|
4
|
+
import type { ConversationCreatorFilter } from './chat.js';
|
|
4
5
|
import type { ChatLoadingMessageMode } from '../utils/chat-loading-messages.js';
|
|
5
6
|
import type { ChatActor, ChatFeatureConfig } from '../utils/tela-chat.js';
|
|
6
7
|
export type ChatEmbedSharedProps = {
|
|
@@ -10,6 +11,8 @@ export type ChatEmbedSharedProps = {
|
|
|
10
11
|
initialConversationId?: string | null;
|
|
11
12
|
/** Technical scope that isolates conversation history within the current workspace and runtime. */
|
|
12
13
|
conversationScope?: string | null;
|
|
14
|
+
/** Initial creator filter for the sidebar conversation list. Defaults to all conversations. */
|
|
15
|
+
defaultConversationCreatorFilter?: ConversationCreatorFilter;
|
|
13
16
|
/** Hide the conversation list and render only the active chat surface. */
|
|
14
17
|
hideSidebar?: boolean;
|
|
15
18
|
/** Hide workspace settings actions while keeping the chat header and content unchanged. */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ConversationCreatorFilter } from '../types/chat.js';
|
|
2
|
+
type ConversationCreatorFilterCounts = Record<ConversationCreatorFilter, number>;
|
|
3
|
+
export declare function resolveConversationCreatorFilterKeyboardTarget(currentFilter: ConversationCreatorFilter, key: string): ConversationCreatorFilter | null;
|
|
4
|
+
export declare function hasConversationCreatorFilterResults(counts: ConversationCreatorFilterCounts): boolean;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CONVERSATION_CREATOR_FILTER_OPTIONS } from "../types/chat.js";
|
|
2
|
+
const FILTER_NAVIGATION_KEYS = {
|
|
3
|
+
ArrowLeft: -1,
|
|
4
|
+
ArrowUp: -1,
|
|
5
|
+
ArrowRight: 1,
|
|
6
|
+
ArrowDown: 1
|
|
7
|
+
};
|
|
8
|
+
export function resolveConversationCreatorFilterKeyboardTarget(currentFilter, key) {
|
|
9
|
+
const filters = CONVERSATION_CREATOR_FILTER_OPTIONS.map((option) => option.value);
|
|
10
|
+
if (key === "Home")
|
|
11
|
+
return filters[0] ?? null;
|
|
12
|
+
if (key === "End")
|
|
13
|
+
return filters.at(-1) ?? null;
|
|
14
|
+
if (!(key in FILTER_NAVIGATION_KEYS))
|
|
15
|
+
return null;
|
|
16
|
+
const currentIndex = filters.indexOf(currentFilter);
|
|
17
|
+
if (currentIndex === -1)
|
|
18
|
+
return null;
|
|
19
|
+
const direction = FILTER_NAVIGATION_KEYS[key];
|
|
20
|
+
return filters[(currentIndex + direction + filters.length) % filters.length] ?? null;
|
|
21
|
+
}
|
|
22
|
+
export function hasConversationCreatorFilterResults(counts) {
|
|
23
|
+
return CONVERSATION_CREATOR_FILTER_OPTIONS.some((option) => counts[option.value] > 0);
|
|
24
|
+
}
|