Files
Memoh/internal/db/sqlc/conversations.sql.go
T
Acbox Liu ea719f7ca7 refactor: memory provider (#140)
* refactor: memory provider

* fix: migrations

* feat: divide collection from different built-in memory

* feat: add `MEMORY.md` and `PROFILES.md`

* use .env for docker compose. fix #142 (#143)

* feat(web): add brand icons for search providers (#144)

Add custom FontAwesome icon definitions for all 9 search providers:
- Yandex: uses existing faYandex from FA free brands
- Tavily, Jina, Exa, Bocha, Serper: custom icons from brand SVGs
- DuckDuckGo, SearXNG, Sogou: custom icons from Simple Icons

Icons are registered with a custom 'fac' prefix and rendered as
monochrome (currentColor) via FontAwesome's standard rendering.

* fix: resolve multiple UI bugs (#147)

* feat: add email service with multi-adapter support (#146)

* feat: add email service with multi-adapter support

Implement a full-stack email service with global provider management,
per-bot bindings with granular read/write permissions, outbox audit
storage, and MCP tool integration for direct mailbox access.

Backend:
- Email providers: CRUD with dynamic config schema (generic SMTP/IMAP, Mailgun)
- Generic adapter: go-mail (SMTP) + go-imap/v2 (IMAP IDLE real-time push via
  UnilateralDataHandler + UID-based tracking + periodic check fallback)
- Mailgun adapter: mailgun-go/v5 with dual inbound mode (webhook + poll)
- Bot email bindings: per-bot provider binding with independent r/w permissions
- Outbox: outbound email audit log with status tracking
- Trigger: inbound emails push notification to bot_inbox (from/subject only,
  LLM reads full content on demand via MCP tools)
- MailboxReader interface: on-demand IMAP queries for listing/reading emails
- MCP tools: email_accounts, email_send, email_list (paginated mailbox),
  email_read (by UID) — all with multi-binding and provider_id selection
- Webhook: /email/mailgun/webhook/:config_id (JWT-skipped, signature-verified)
- DB migration: 0019_add_email (email_providers, bot_email_bindings, email_outbox)

Frontend:
- Email Providers page: /email-providers with MasterDetailSidebarLayout
- Dynamic config form rendered from ordered provider meta schema with i18n keys
- Bot detail: Email tab with bindings management + outbox audit table
- Sidebar navigation entry
- Full i18n support (en + zh)
- Auto-generated SDK from Swagger

Closes #17

* feat(email): trigger bot conversation immediately on inbound email

Instead of only storing an inbox item and waiting for the next chat,
the email trigger now proactively invokes the conversation resolver
so the bot processes new emails right away — aligned with the
schedule/heartbeat trigger pattern.

* fix: lint

---------

Co-authored-by: Acbox <acbox0328@gmail.com>

* chore: update AGENTS.md

* feat: files preview

* feat(web): improve MCP details page

* refactor(skills): import skill with pure markdown string

* merge main into refactor/memory

* fix: migration

* refactor: temp delete qdrant and bm25 index

* fix: clean merge code

* fix: update memory handler

---------

Co-authored-by: Leohearts <leohearts@leohearts.com>
Co-authored-by: Menci <mencici@msn.com>
Co-authored-by: Quincy <69751197+dqygit@users.noreply.github.com>
Co-authored-by: BBQ <35603386+HoneyBBQ@users.noreply.github.com>
Co-authored-by: Ran <16112591+chen-ran@users.noreply.github.com>
2026-03-03 15:33:50 +08:00

682 lines
20 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: conversations.sql
package sqlc
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const addChatParticipant = `-- name: AddChatParticipant :one
INSERT INTO bot_members (bot_id, user_id, role)
VALUES ($1, $2, $3)
ON CONFLICT (bot_id, user_id) DO UPDATE SET role = EXCLUDED.role
RETURNING bot_id AS chat_id, user_id, role, created_at AS joined_at
`
type AddChatParticipantParams struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
Role string `json:"role"`
}
type AddChatParticipantRow struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
Role string `json:"role"`
JoinedAt pgtype.Timestamptz `json:"joined_at"`
}
// chat_participants
func (q *Queries) AddChatParticipant(ctx context.Context, arg AddChatParticipantParams) (AddChatParticipantRow, error) {
row := q.db.QueryRow(ctx, addChatParticipant, arg.ChatID, arg.UserID, arg.Role)
var i AddChatParticipantRow
err := row.Scan(
&i.ChatID,
&i.UserID,
&i.Role,
&i.JoinedAt,
)
return i, err
}
const copyParticipantsToChat = `-- name: CopyParticipantsToChat :exec
INSERT INTO bot_members (bot_id, user_id, role)
SELECT $1, bm.user_id, bm.role
FROM bot_members bm
WHERE bm.bot_id = $2
ON CONFLICT (bot_id, user_id) DO NOTHING
`
type CopyParticipantsToChatParams struct {
ChatID2 pgtype.UUID `json:"chat_id_2"`
ChatID pgtype.UUID `json:"chat_id"`
}
func (q *Queries) CopyParticipantsToChat(ctx context.Context, arg CopyParticipantsToChatParams) error {
_, err := q.db.Exec(ctx, copyParticipantsToChat, arg.ChatID2, arg.ChatID)
return err
}
const createChat = `-- name: CreateChat :one
SELECT
b.id AS id,
b.id AS bot_id,
(COALESCE(NULLIF($1::text, ''), CASE WHEN b.type = 'public' THEN 'group' ELSE 'direct' END))::text AS kind,
CASE WHEN $1 = 'thread' THEN $2::uuid ELSE NULL::uuid END AS parent_chat_id,
COALESCE(NULLIF($3::text, ''), b.display_name) AS title,
COALESCE($4::uuid, b.owner_user_id) AS created_by_user_id,
COALESCE($5::jsonb, b.metadata) AS metadata,
chat_models.model_id AS model_id,
b.created_at,
b.updated_at
FROM bots b
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $6
LIMIT 1
`
type CreateChatParams struct {
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title string `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
BotID pgtype.UUID `json:"bot_id"`
}
type CreateChatRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) CreateChat(ctx context.Context, arg CreateChatParams) (CreateChatRow, error) {
row := q.db.QueryRow(ctx, createChat,
arg.Kind,
arg.ParentChatID,
arg.Title,
arg.CreatedByUserID,
arg.Metadata,
arg.BotID,
)
var i CreateChatRow
err := row.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const deleteChat = `-- name: DeleteChat :exec
WITH deleted_messages AS (
DELETE FROM bot_history_messages
WHERE bot_id = $1
)
DELETE FROM bot_channel_routes bcr
WHERE bcr.bot_id = $1
`
func (q *Queries) DeleteChat(ctx context.Context, chatID pgtype.UUID) error {
_, err := q.db.Exec(ctx, deleteChat, chatID)
return err
}
const getChatByID = `-- name: GetChatByID :one
SELECT
b.id AS id,
b.id AS bot_id,
CASE WHEN b.type = 'public' THEN 'group' ELSE 'direct' END AS kind,
NULL::uuid AS parent_chat_id,
b.display_name AS title,
b.owner_user_id AS created_by_user_id,
b.metadata AS metadata,
chat_models.model_id AS model_id,
b.created_at,
b.updated_at
FROM bots b
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $1
`
type GetChatByIDRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetChatByID(ctx context.Context, id pgtype.UUID) (GetChatByIDRow, error) {
row := q.db.QueryRow(ctx, getChatByID, id)
var i GetChatByIDRow
err := row.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getChatParticipant = `-- name: GetChatParticipant :one
WITH owner_participant AS (
SELECT b.id AS chat_id, b.owner_user_id AS user_id, 'owner'::text AS role, b.created_at AS joined_at
FROM bots b
WHERE b.id = $1 AND b.owner_user_id = $2
),
member_participant AS (
SELECT bm.bot_id AS chat_id, bm.user_id, bm.role, bm.created_at AS joined_at
FROM bot_members bm
WHERE bm.bot_id = $1 AND bm.user_id = $2
)
SELECT chat_id, user_id, role, joined_at
FROM (
SELECT chat_id, user_id, role, joined_at FROM owner_participant
UNION ALL
SELECT chat_id, user_id, role, joined_at FROM member_participant
) p
ORDER BY CASE WHEN role = 'owner' THEN 0 ELSE 1 END
LIMIT 1
`
type GetChatParticipantParams struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
}
type GetChatParticipantRow struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
Role string `json:"role"`
JoinedAt pgtype.Timestamptz `json:"joined_at"`
}
func (q *Queries) GetChatParticipant(ctx context.Context, arg GetChatParticipantParams) (GetChatParticipantRow, error) {
row := q.db.QueryRow(ctx, getChatParticipant, arg.ChatID, arg.UserID)
var i GetChatParticipantRow
err := row.Scan(
&i.ChatID,
&i.UserID,
&i.Role,
&i.JoinedAt,
)
return i, err
}
const getChatReadAccessByUser = `-- name: GetChatReadAccessByUser :one
SELECT
'participant'::text AS access_mode,
(CASE
WHEN b.owner_user_id = $1 THEN 'owner'
ELSE COALESCE(bm.role, ''::text)
END)::text AS participant_role,
NULL::timestamptz AS last_observed_at
FROM bots b
LEFT JOIN bot_members bm ON bm.bot_id = b.id AND bm.user_id = $1
WHERE b.id = $2
AND (b.owner_user_id = $1 OR bm.user_id IS NOT NULL)
LIMIT 1
`
type GetChatReadAccessByUserParams struct {
UserID pgtype.UUID `json:"user_id"`
ChatID pgtype.UUID `json:"chat_id"`
}
type GetChatReadAccessByUserRow struct {
AccessMode string `json:"access_mode"`
ParticipantRole string `json:"participant_role"`
LastObservedAt pgtype.Timestamptz `json:"last_observed_at"`
}
func (q *Queries) GetChatReadAccessByUser(ctx context.Context, arg GetChatReadAccessByUserParams) (GetChatReadAccessByUserRow, error) {
row := q.db.QueryRow(ctx, getChatReadAccessByUser, arg.UserID, arg.ChatID)
var i GetChatReadAccessByUserRow
err := row.Scan(&i.AccessMode, &i.ParticipantRole, &i.LastObservedAt)
return i, err
}
const getChatSettings = `-- name: GetChatSettings :one
SELECT
b.id AS chat_id,
chat_models.id AS model_id,
b.updated_at
FROM bots b
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $1
`
type GetChatSettingsRow struct {
ChatID pgtype.UUID `json:"chat_id"`
ModelID pgtype.UUID `json:"model_id"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetChatSettings(ctx context.Context, id pgtype.UUID) (GetChatSettingsRow, error) {
row := q.db.QueryRow(ctx, getChatSettings, id)
var i GetChatSettingsRow
err := row.Scan(&i.ChatID, &i.ModelID, &i.UpdatedAt)
return i, err
}
const listChatParticipants = `-- name: ListChatParticipants :many
WITH owner_participant AS (
SELECT b.id AS chat_id, b.owner_user_id AS user_id, 'owner'::text AS role, b.created_at AS joined_at
FROM bots b
WHERE b.id = $1
),
member_participant AS (
SELECT bm.bot_id AS chat_id, bm.user_id, bm.role, bm.created_at AS joined_at
FROM bot_members bm
WHERE bm.bot_id = $1
AND bm.user_id <> (SELECT owner_user_id FROM bots WHERE id = $1)
)
SELECT chat_id, user_id, role, joined_at
FROM (
SELECT chat_id, user_id, role, joined_at FROM owner_participant
UNION ALL
SELECT chat_id, user_id, role, joined_at FROM member_participant
) p
ORDER BY joined_at ASC
`
type ListChatParticipantsRow struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
Role string `json:"role"`
JoinedAt pgtype.Timestamptz `json:"joined_at"`
}
func (q *Queries) ListChatParticipants(ctx context.Context, chatID pgtype.UUID) ([]ListChatParticipantsRow, error) {
rows, err := q.db.Query(ctx, listChatParticipants, chatID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListChatParticipantsRow
for rows.Next() {
var i ListChatParticipantsRow
if err := rows.Scan(
&i.ChatID,
&i.UserID,
&i.Role,
&i.JoinedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listChatsByBotAndUser = `-- name: ListChatsByBotAndUser :many
SELECT
b.id AS id,
b.id AS bot_id,
CASE WHEN b.type = 'public' THEN 'group' ELSE 'direct' END AS kind,
NULL::uuid AS parent_chat_id,
b.display_name AS title,
b.owner_user_id AS created_by_user_id,
b.metadata AS metadata,
chat_models.model_id AS model_id,
b.created_at,
b.updated_at
FROM bots b
LEFT JOIN bot_members bm ON bm.bot_id = b.id AND bm.user_id = $1
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $2
AND (b.owner_user_id = $1 OR bm.user_id IS NOT NULL)
ORDER BY b.updated_at DESC
`
type ListChatsByBotAndUserParams struct {
UserID pgtype.UUID `json:"user_id"`
BotID pgtype.UUID `json:"bot_id"`
}
type ListChatsByBotAndUserRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) ListChatsByBotAndUser(ctx context.Context, arg ListChatsByBotAndUserParams) ([]ListChatsByBotAndUserRow, error) {
rows, err := q.db.Query(ctx, listChatsByBotAndUser, arg.UserID, arg.BotID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListChatsByBotAndUserRow
for rows.Next() {
var i ListChatsByBotAndUserRow
if err := rows.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listThreadsByParent = `-- name: ListThreadsByParent :many
SELECT
b.id AS id,
b.id AS bot_id,
CASE WHEN b.type = 'public' THEN 'group' ELSE 'direct' END AS kind,
NULL::uuid AS parent_chat_id,
b.display_name AS title,
b.owner_user_id AS created_by_user_id,
b.metadata AS metadata,
chat_models.model_id AS model_id,
b.created_at,
b.updated_at
FROM bots b
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $1
ORDER BY b.created_at DESC
`
type ListThreadsByParentRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) ListThreadsByParent(ctx context.Context, id pgtype.UUID) ([]ListThreadsByParentRow, error) {
rows, err := q.db.Query(ctx, listThreadsByParent, id)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListThreadsByParentRow
for rows.Next() {
var i ListThreadsByParentRow
if err := rows.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listVisibleChatsByBotAndUser = `-- name: ListVisibleChatsByBotAndUser :many
SELECT
b.id AS id,
b.id AS bot_id,
CASE WHEN b.type = 'public' THEN 'group' ELSE 'direct' END AS kind,
NULL::uuid AS parent_chat_id,
b.display_name AS title,
b.owner_user_id AS created_by_user_id,
b.metadata AS metadata,
chat_models.model_id AS model_id,
b.created_at,
b.updated_at,
'participant'::text AS access_mode,
(CASE
WHEN b.owner_user_id = $1 THEN 'owner'
ELSE COALESCE(bm.role, ''::text)
END)::text AS participant_role,
NULL::timestamptz AS last_observed_at
FROM bots b
LEFT JOIN bot_members bm ON bm.bot_id = b.id AND bm.user_id = $1
LEFT JOIN models chat_models ON chat_models.id = b.chat_model_id
WHERE b.id = $2
AND (b.owner_user_id = $1 OR bm.user_id IS NOT NULL)
ORDER BY b.updated_at DESC
`
type ListVisibleChatsByBotAndUserParams struct {
UserID pgtype.UUID `json:"user_id"`
BotID pgtype.UUID `json:"bot_id"`
}
type ListVisibleChatsByBotAndUserRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
AccessMode string `json:"access_mode"`
ParticipantRole string `json:"participant_role"`
LastObservedAt pgtype.Timestamptz `json:"last_observed_at"`
}
func (q *Queries) ListVisibleChatsByBotAndUser(ctx context.Context, arg ListVisibleChatsByBotAndUserParams) ([]ListVisibleChatsByBotAndUserRow, error) {
rows, err := q.db.Query(ctx, listVisibleChatsByBotAndUser, arg.UserID, arg.BotID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListVisibleChatsByBotAndUserRow
for rows.Next() {
var i ListVisibleChatsByBotAndUserRow
if err := rows.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
&i.AccessMode,
&i.ParticipantRole,
&i.LastObservedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const removeChatParticipant = `-- name: RemoveChatParticipant :exec
DELETE FROM bot_members
WHERE bot_id = $1
AND user_id = $2
AND user_id <> (SELECT owner_user_id FROM bots WHERE id = $1)
`
type RemoveChatParticipantParams struct {
ChatID pgtype.UUID `json:"chat_id"`
UserID pgtype.UUID `json:"user_id"`
}
func (q *Queries) RemoveChatParticipant(ctx context.Context, arg RemoveChatParticipantParams) error {
_, err := q.db.Exec(ctx, removeChatParticipant, arg.ChatID, arg.UserID)
return err
}
const touchChat = `-- name: TouchChat :exec
UPDATE bots
SET updated_at = now()
WHERE id = $1
`
func (q *Queries) TouchChat(ctx context.Context, chatID pgtype.UUID) error {
_, err := q.db.Exec(ctx, touchChat, chatID)
return err
}
const updateChatTitle = `-- name: UpdateChatTitle :one
WITH updated AS (
UPDATE bots
SET display_name = $1,
updated_at = now()
WHERE bots.id = $2
RETURNING id, owner_user_id, type, display_name, avatar_url, is_active, status, max_context_load_time, max_context_tokens, language, allow_guest, reasoning_enabled, reasoning_effort, max_inbox_items, chat_model_id, search_provider_id, memory_provider_id, heartbeat_enabled, heartbeat_interval, heartbeat_prompt, heartbeat_model_id, metadata, created_at, updated_at
)
SELECT
updated.id AS id,
updated.id AS bot_id,
CASE WHEN updated.type = 'public' THEN 'group' ELSE 'direct' END AS kind,
NULL::uuid AS parent_chat_id,
updated.display_name AS title,
updated.owner_user_id AS created_by_user_id,
updated.metadata,
chat_models.model_id AS model_id,
updated.created_at,
updated.updated_at
FROM updated
LEFT JOIN models chat_models ON chat_models.id = updated.chat_model_id
`
type UpdateChatTitleParams struct {
Title pgtype.Text `json:"title"`
BotID pgtype.UUID `json:"bot_id"`
}
type UpdateChatTitleRow struct {
ID pgtype.UUID `json:"id"`
BotID pgtype.UUID `json:"bot_id"`
Kind string `json:"kind"`
ParentChatID pgtype.UUID `json:"parent_chat_id"`
Title pgtype.Text `json:"title"`
CreatedByUserID pgtype.UUID `json:"created_by_user_id"`
Metadata []byte `json:"metadata"`
ModelID pgtype.Text `json:"model_id"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) UpdateChatTitle(ctx context.Context, arg UpdateChatTitleParams) (UpdateChatTitleRow, error) {
row := q.db.QueryRow(ctx, updateChatTitle, arg.Title, arg.BotID)
var i UpdateChatTitleRow
err := row.Scan(
&i.ID,
&i.BotID,
&i.Kind,
&i.ParentChatID,
&i.Title,
&i.CreatedByUserID,
&i.Metadata,
&i.ModelID,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const upsertChatSettings = `-- name: UpsertChatSettings :one
WITH
updated AS (
UPDATE bots
SET chat_model_id = COALESCE($1::uuid, bots.chat_model_id),
updated_at = now()
WHERE bots.id = $2
RETURNING bots.id, bots.chat_model_id, bots.updated_at
)
SELECT
updated.id AS chat_id,
chat_models.id AS model_id,
updated.updated_at
FROM updated
LEFT JOIN models chat_models ON chat_models.id = updated.chat_model_id
`
type UpsertChatSettingsParams struct {
ChatModelID pgtype.UUID `json:"chat_model_id"`
ID pgtype.UUID `json:"id"`
}
type UpsertChatSettingsRow struct {
ChatID pgtype.UUID `json:"chat_id"`
ModelID pgtype.UUID `json:"model_id"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
// chat_settings
func (q *Queries) UpsertChatSettings(ctx context.Context, arg UpsertChatSettingsParams) (UpsertChatSettingsRow, error) {
row := q.db.QueryRow(ctx, upsertChatSettings, arg.ChatModelID, arg.ID)
var i UpsertChatSettingsRow
err := row.Scan(&i.ChatID, &i.ModelID, &i.UpdatedAt)
return i, err
}