mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-27 10:38:21 +03:00
Compare commits
25 Commits
ba4d4d242a
...
aec7c15b6f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aec7c15b6f | ||
|
|
a5755c806b | ||
|
|
ce33ae0bbc | ||
|
|
361dcc94c8 | ||
|
|
d4630c62ca | ||
|
|
994a5acc52 | ||
|
|
2ddd55c470 | ||
|
|
7f69233f71 | ||
|
|
7551332c01 | ||
|
|
76409f79e0 | ||
|
|
730bf3c0b7 | ||
|
|
0371f55321 | ||
|
|
858367c98a | ||
|
|
e09e9a0b7a | ||
|
|
3b3edc481b | ||
|
|
b0bcf45245 | ||
|
|
910122913a | ||
|
|
99e97850c9 | ||
|
|
59a38aa67c | ||
|
|
9125eff794 | ||
|
|
e934910616 | ||
|
|
a21cabae2d | ||
|
|
79d7d20866 | ||
|
|
e7e806b135 | ||
|
|
f29adca9ce |
@ -69,7 +69,6 @@ class LlamaCppClient(GenAIClient):
|
||||
|
||||
# Build request payload with llama.cpp native options
|
||||
payload = {
|
||||
"model": self.genai_config.model,
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
@ -121,7 +120,7 @@ class LlamaCppClient(GenAIClient):
|
||||
elif tool_choice == "required":
|
||||
openai_tool_choice = "required"
|
||||
|
||||
payload: dict[str, Any] = {"messages": messages, "model": self.genai_config.model}
|
||||
payload: dict[str, Any] = {"messages": messages}
|
||||
if stream:
|
||||
payload["stream"] = True
|
||||
if tools:
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
import { useApiHost } from "@/api";
|
||||
|
||||
type ChatEventThumbnailsRowProps = {
|
||||
events: { id: string }[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Horizontal scroll row of event thumbnail images for chat (e.g. after search_objects).
|
||||
* Renders nothing when events is empty.
|
||||
*/
|
||||
export function ChatEventThumbnailsRow({
|
||||
events,
|
||||
}: ChatEventThumbnailsRowProps) {
|
||||
const apiHost = useApiHost();
|
||||
|
||||
if (events.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div className="flex min-w-0 max-w-full flex-col gap-1 self-start">
|
||||
<div className="scrollbar-container min-w-0 overflow-x-auto">
|
||||
<div className="flex w-max gap-2">
|
||||
{events.map((event) => (
|
||||
<a
|
||||
key={event.id}
|
||||
href={`/explore?event_id=${event.id}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="relative aspect-square size-32 shrink-0 overflow-hidden rounded-lg"
|
||||
>
|
||||
<img
|
||||
className="size-full object-cover"
|
||||
src={`${apiHost}api/events/${event.id}/thumbnail.webp`}
|
||||
alt=""
|
||||
loading="lazy"
|
||||
/>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -4,14 +4,10 @@ import { FaArrowUpLong } from "react-icons/fa6";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useState, useCallback } from "react";
|
||||
import axios from "axios";
|
||||
import { ChatEventThumbnailsRow } from "@/components/chat/ChatEventThumbnailsRow";
|
||||
import { MessageBubble } from "@/components/chat/ChatMessage";
|
||||
import { ToolCallBubble } from "@/components/chat/ToolCallBubble";
|
||||
import type { ChatMessage } from "@/types/chat";
|
||||
import {
|
||||
getEventIdsFromSearchObjectsToolCalls,
|
||||
streamChatCompletion,
|
||||
} from "@/utils/chatUtil";
|
||||
import { streamChatCompletion } from "@/utils/chatUtil";
|
||||
|
||||
export default function ChatPage() {
|
||||
const { t } = useTranslation(["views/chat"]);
|
||||
@ -122,15 +118,6 @@ export default function ChatPage() {
|
||||
msg.role === "user" || !isLoading || i < messages.length - 1
|
||||
}
|
||||
/>
|
||||
{msg.role === "assistant" &&
|
||||
(() => {
|
||||
const isComplete = !isLoading || i < messages.length - 1;
|
||||
if (!isComplete) return null;
|
||||
const events = getEventIdsFromSearchObjectsToolCalls(
|
||||
msg.toolCalls,
|
||||
);
|
||||
return <ChatEventThumbnailsRow events={events} />;
|
||||
})()}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -161,33 +161,3 @@ export async function streamChatCompletion(
|
||||
onDone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse search_objects tool call response(s) into event ids for thumbnails.
|
||||
*/
|
||||
export function getEventIdsFromSearchObjectsToolCalls(
|
||||
toolCalls: ToolCall[] | undefined,
|
||||
): { id: string }[] {
|
||||
if (!toolCalls?.length) return [];
|
||||
const results: { id: string }[] = [];
|
||||
for (const tc of toolCalls) {
|
||||
if (tc.name !== "search_objects" || !tc.response?.trim()) continue;
|
||||
try {
|
||||
const parsed = JSON.parse(tc.response) as unknown;
|
||||
if (!Array.isArray(parsed)) continue;
|
||||
for (const item of parsed) {
|
||||
if (
|
||||
item &&
|
||||
typeof item === "object" &&
|
||||
"id" in item &&
|
||||
typeof (item as { id: unknown }).id === "string"
|
||||
) {
|
||||
results.push({ id: (item as { id: string }).id });
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore parse errors
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user