mirror of
https://github.com/kennethnym/freya
synced 2026-07-04 23:21:13 +01:00
Compare commits
1 Commits
feat/core-
...
feat/upgra
| Author | SHA1 | Date | |
|---|---|---|---|
|
f94ac4931e
|
19
.nvim.lua
19
.nvim.lua
@@ -1,19 +0,0 @@
|
|||||||
local ok, conform = pcall(require, "conform")
|
|
||||||
if not ok then
|
|
||||||
vim.notify("conform.nvim not loaded", vim.log.levels.WARN)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
conform.setup({
|
|
||||||
formatters_by_ft = {
|
|
||||||
javascript = { "oxfmt" },
|
|
||||||
javascriptreact = { "oxfmt" },
|
|
||||||
typescript = { "oxfmt" },
|
|
||||||
typescriptreact = { "oxfmt" },
|
|
||||||
json = { "oxfmt" },
|
|
||||||
jsonc = { "oxfmt" },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.lsp.enable("tsgo")
|
|
||||||
vim.lsp.enable("oxlint")
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
// Folder-specific settings
|
|
||||||
//
|
|
||||||
// For a full list of overridable settings, and general information on folder-specific settings,
|
|
||||||
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
|
|
||||||
{
|
|
||||||
"languages": {
|
|
||||||
"TypeScript": {
|
|
||||||
"formatter": { "language_server": { "name": "oxfmt" } }
|
|
||||||
},
|
|
||||||
"TSX": {
|
|
||||||
"formatter": { "language_server": { "name": "oxfmt" } }
|
|
||||||
},
|
|
||||||
"JavaScript": {
|
|
||||||
"formatter": { "language_server": { "name": "oxfmt" } }
|
|
||||||
},
|
|
||||||
"JSX": {
|
|
||||||
"formatter": { "language_server": { "name": "oxfmt" } }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,12 @@
|
|||||||
import type { Context, Hono } from "hono"
|
import type { Context, Hono } from "hono"
|
||||||
|
|
||||||
import {
|
import { ConversationEntryVisibility } from "@freya/core"
|
||||||
AssistantMessagePayload,
|
|
||||||
AttachmentPayload,
|
|
||||||
ConversationEntryKind,
|
|
||||||
ConversationEntryVisibility,
|
|
||||||
ContextSummaryPayload,
|
|
||||||
GenericObjectPayload,
|
|
||||||
UserMessagePayload,
|
|
||||||
type Conversation,
|
|
||||||
type ConversationEntry,
|
|
||||||
} from "@freya/core"
|
|
||||||
import { type } from "arktype"
|
import { type } from "arktype"
|
||||||
import { createMiddleware } from "hono/factory"
|
import { createMiddleware } from "hono/factory"
|
||||||
|
|
||||||
import type { AuthSessionMiddleware } from "../auth/session-middleware.ts"
|
import type { AuthSessionMiddleware } from "../auth/session-middleware.ts"
|
||||||
import type { Database } from "../db/index.ts"
|
import type { Database } from "../db/index.ts"
|
||||||
import type { ConversationEntryRow, ConversationRow } from "./storage.ts"
|
import type { ConversationRow } from "./storage.ts"
|
||||||
|
|
||||||
import { ConversationNotFoundError } from "./errors.ts"
|
import { ConversationNotFoundError } from "./errors.ts"
|
||||||
import { conversations } from "./storage.ts"
|
import { conversations } from "./storage.ts"
|
||||||
@@ -28,20 +18,19 @@ type Env = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Serialized conversation summary returned by the list endpoint. */
|
||||||
|
interface ConversationSummaryResponse {
|
||||||
|
id: string
|
||||||
|
createdAt: string
|
||||||
|
updatedAt: string
|
||||||
|
}
|
||||||
|
|
||||||
/** Dependencies required to register conversation HTTP handlers. */
|
/** Dependencies required to register conversation HTTP handlers. */
|
||||||
interface ConversationsHttpHandlersDeps {
|
interface ConversationsHttpHandlersDeps {
|
||||||
db: Database
|
db: Database
|
||||||
authSessionMiddleware: AuthSessionMiddleware
|
authSessionMiddleware: AuthSessionMiddleware
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ListConversationsResponse {
|
|
||||||
conversations: Conversation[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ListConversationEntriesResponse {
|
|
||||||
entries: ConversationEntry[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConversationIdParam = type("string.uuid")
|
const ConversationIdParam = type("string.uuid")
|
||||||
|
|
||||||
export function registerConversationsHttpHandlers(
|
export function registerConversationsHttpHandlers(
|
||||||
@@ -60,13 +49,12 @@ export function registerConversationsHttpHandlers(
|
|||||||
async function handleListConversations(c: Context<Env>) {
|
async function handleListConversations(c: Context<Env>) {
|
||||||
const user = c.get("user")!
|
const user = c.get("user")!
|
||||||
const db = c.get("db")
|
const db = c.get("db")
|
||||||
const response: ListConversationsResponse = {
|
|
||||||
|
return c.json({
|
||||||
conversations: (await conversations(db, user.id).listConversations()).map(
|
conversations: (await conversations(db, user.id).listConversations()).map(
|
||||||
serializeConversation,
|
serializeConversation,
|
||||||
),
|
),
|
||||||
}
|
})
|
||||||
|
|
||||||
return c.json(response)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleListEntries(c: Context<Env>) {
|
async function handleListEntries(c: Context<Env>) {
|
||||||
@@ -85,11 +73,20 @@ async function handleListEntries(c: Context<Env>) {
|
|||||||
const entries = await conversations(db, user.id).listEntries(parsedConversationId, {
|
const entries = await conversations(db, user.id).listEntries(parsedConversationId, {
|
||||||
visibility: ConversationEntryVisibility.UserVisible,
|
visibility: ConversationEntryVisibility.UserVisible,
|
||||||
})
|
})
|
||||||
const response: ListConversationEntriesResponse = {
|
|
||||||
entries: entries.map(serializeConversationEntry),
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.json(response)
|
return c.json({
|
||||||
|
entries: entries.map((row) => ({
|
||||||
|
id: row.id,
|
||||||
|
conversationId: row.conversationId,
|
||||||
|
sequence: row.sequence,
|
||||||
|
kind: row.kind,
|
||||||
|
visibility: row.visibility,
|
||||||
|
fileId: row.fileId,
|
||||||
|
payload: row.payload,
|
||||||
|
metadata: row.metadata,
|
||||||
|
createdAt: row.createdAt.toISOString(),
|
||||||
|
})),
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof ConversationNotFoundError) {
|
if (err instanceof ConversationNotFoundError) {
|
||||||
return c.json({ error: "Conversation not found" }, 404)
|
return c.json({ error: "Conversation not found" }, 404)
|
||||||
@@ -98,89 +95,10 @@ async function handleListEntries(c: Context<Env>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeConversation(row: ConversationRow): Conversation {
|
function serializeConversation(row: ConversationRow): ConversationSummaryResponse {
|
||||||
return {
|
return {
|
||||||
id: row.id,
|
id: row.id,
|
||||||
createdAt: row.createdAt.toISOString(),
|
createdAt: row.createdAt.toISOString(),
|
||||||
updatedAt: row.updatedAt.toISOString(),
|
updatedAt: row.updatedAt.toISOString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function serializeConversationEntry(row: ConversationEntryRow): ConversationEntry {
|
|
||||||
const base = {
|
|
||||||
id: row.id,
|
|
||||||
conversationId: row.conversationId,
|
|
||||||
sequence: row.sequence,
|
|
||||||
visibility: row.visibility,
|
|
||||||
metadata: row.metadata,
|
|
||||||
createdAt: row.createdAt.toISOString(),
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (row.kind) {
|
|
||||||
case ConversationEntryKind.UserMessage:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: UserMessagePayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.AssistantMessage:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: AssistantMessagePayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.Attachment:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: requireFileId(row),
|
|
||||||
payload: AttachmentPayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.ToolCall:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: GenericObjectPayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.ToolResult:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: GenericObjectPayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.ContextSummary:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: ContextSummaryPayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
case ConversationEntryKind.SystemNote:
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
kind: row.kind,
|
|
||||||
fileId: nullFileId(row),
|
|
||||||
payload: GenericObjectPayload.assert(row.payload),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function requireFileId(row: ConversationEntryRow): string {
|
|
||||||
if (!row.fileId) {
|
|
||||||
throw new Error(`Conversation attachment entry "${row.id}" is missing a file id`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return row.fileId
|
|
||||||
}
|
|
||||||
|
|
||||||
function nullFileId(row: ConversationEntryRow): null {
|
|
||||||
if (row.fileId !== null) {
|
|
||||||
throw new Error(`Conversation entry "${row.id}" unexpectedly references a file`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|||||||
18
flake.nix
18
flake.nix
@@ -53,10 +53,9 @@
|
|||||||
# so source-only edits do not force Bun to reinstall.
|
# so source-only edits do not force Bun to reinstall.
|
||||||
dependencySource = lib.fileset.toSource {
|
dependencySource = lib.fileset.toSource {
|
||||||
root = ./.;
|
root = ./.;
|
||||||
fileset = lib.fileset.fileFilter
|
fileset = lib.fileset.fileFilter (
|
||||||
(
|
file: file.name == "bun.lock" || file.name == "package.json" || file.name == "bunfig.toml"
|
||||||
file: file.name == "bun.lock" || file.name == "package.json" || file.name == "bunfig.toml"
|
) ./.;
|
||||||
) ./.;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Checks run against a clean source tree, even when using `path:.`.
|
# Checks run against a clean source tree, even when using `path:.`.
|
||||||
@@ -93,12 +92,10 @@
|
|||||||
lib.mapAttrs mkBunScript scripts;
|
lib.mapAttrs mkBunScript scripts;
|
||||||
mkBunApps =
|
mkBunApps =
|
||||||
commands:
|
commands:
|
||||||
lib.mapAttrs
|
lib.mapAttrs (name: command: {
|
||||||
(name: command: {
|
type = "app";
|
||||||
type = "app";
|
program = "${command}/bin/${name}";
|
||||||
program = "${command}/bin/${name}";
|
}) commands;
|
||||||
})
|
|
||||||
commands;
|
|
||||||
mkBunNodeModules =
|
mkBunNodeModules =
|
||||||
system: pkgs:
|
system: pkgs:
|
||||||
pkgs.stdenvNoCC.mkDerivation {
|
pkgs.stdenvNoCC.mkDerivation {
|
||||||
@@ -258,7 +255,6 @@
|
|||||||
pkg-config
|
pkg-config
|
||||||
postgresql
|
postgresql
|
||||||
python3
|
python3
|
||||||
typescript-go
|
|
||||||
watchman
|
watchman
|
||||||
];
|
];
|
||||||
linuxPackages = with pkgs; [
|
linuxPackages = with pkgs; [
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import {
|
|||||||
AttachmentType,
|
AttachmentType,
|
||||||
AttachmentPayload,
|
AttachmentPayload,
|
||||||
ContextSummaryPayload,
|
ContextSummaryPayload,
|
||||||
Conversation,
|
|
||||||
ConversationEntry,
|
|
||||||
ConversationEntryKind,
|
|
||||||
ConversationEntryMetadata,
|
ConversationEntryMetadata,
|
||||||
ConversationEntryVisibility,
|
|
||||||
GenericObjectPayload,
|
GenericObjectPayload,
|
||||||
UserMessagePayload,
|
UserMessagePayload,
|
||||||
} from "./conversation"
|
} from "./conversation"
|
||||||
@@ -147,99 +143,4 @@ describe("conversation entry schemas", () => {
|
|||||||
}),
|
}),
|
||||||
).toThrow()
|
).toThrow()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("parses conversation summaries", () => {
|
|
||||||
const conversation = Conversation.assert({
|
|
||||||
id: "11111111-1111-4111-8111-111111111111",
|
|
||||||
createdAt: "2026-06-17T09:30:00.000Z",
|
|
||||||
updatedAt: "2026-06-17T09:35:00.000Z",
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(conversation.id).toBe("11111111-1111-4111-8111-111111111111")
|
|
||||||
})
|
|
||||||
|
|
||||||
test("parses kind-specific conversation entries", () => {
|
|
||||||
const userMessageEntry = ConversationEntry.assert({
|
|
||||||
id: "22222222-2222-4222-8222-222222222222",
|
|
||||||
conversationId: "11111111-1111-4111-8111-111111111111",
|
|
||||||
sequence: 1,
|
|
||||||
kind: ConversationEntryKind.UserMessage,
|
|
||||||
visibility: ConversationEntryVisibility.UserVisible,
|
|
||||||
fileId: null,
|
|
||||||
payload: {
|
|
||||||
role: "user",
|
|
||||||
parts: [{ type: "text", text: "hello" }],
|
|
||||||
},
|
|
||||||
metadata: {},
|
|
||||||
createdAt: "2026-06-17T09:30:00.000Z",
|
|
||||||
})
|
|
||||||
const attachmentEntry = ConversationEntry.assert({
|
|
||||||
id: "33333333-3333-4333-8333-333333333333",
|
|
||||||
conversationId: "11111111-1111-4111-8111-111111111111",
|
|
||||||
sequence: 2,
|
|
||||||
kind: ConversationEntryKind.Attachment,
|
|
||||||
visibility: ConversationEntryVisibility.UserVisible,
|
|
||||||
fileId: "44444444-4444-4444-8444-444444444444",
|
|
||||||
payload: {
|
|
||||||
role: "user",
|
|
||||||
name: "photo.png",
|
|
||||||
mimeType: "image/png",
|
|
||||||
attachmentType: AttachmentType.Image,
|
|
||||||
},
|
|
||||||
metadata: {},
|
|
||||||
createdAt: "2026-06-17T09:31:00.000Z",
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(userMessageEntry.kind).toBe(ConversationEntryKind.UserMessage)
|
|
||||||
expect(attachmentEntry.kind).toBe(ConversationEntryKind.Attachment)
|
|
||||||
})
|
|
||||||
|
|
||||||
test("rejects conversation entries whose payload does not match the kind", () => {
|
|
||||||
expect(() =>
|
|
||||||
ConversationEntry.assert({
|
|
||||||
id: "22222222-2222-4222-8222-222222222222",
|
|
||||||
conversationId: "11111111-1111-4111-8111-111111111111",
|
|
||||||
sequence: 1,
|
|
||||||
kind: ConversationEntryKind.UserMessage,
|
|
||||||
visibility: ConversationEntryVisibility.UserVisible,
|
|
||||||
fileId: null,
|
|
||||||
payload: {
|
|
||||||
role: "assistant",
|
|
||||||
parts: [{ type: "text", text: "hello" }],
|
|
||||||
},
|
|
||||||
metadata: {},
|
|
||||||
createdAt: "2026-06-17T09:30:00.000Z",
|
|
||||||
}),
|
|
||||||
).toThrow()
|
|
||||||
})
|
|
||||||
|
|
||||||
test("rejects serialized conversations with extra fields", () => {
|
|
||||||
expect(() =>
|
|
||||||
Conversation.assert({
|
|
||||||
id: "11111111-1111-4111-8111-111111111111",
|
|
||||||
createdAt: "2026-06-17T09:30:00.000Z",
|
|
||||||
updatedAt: "2026-06-17T09:35:00.000Z",
|
|
||||||
title: "not yet part of the schema",
|
|
||||||
}),
|
|
||||||
).toThrow()
|
|
||||||
})
|
|
||||||
|
|
||||||
test("rejects file ids on non-attachment entries", () => {
|
|
||||||
expect(() =>
|
|
||||||
ConversationEntry.assert({
|
|
||||||
id: "22222222-2222-4222-8222-222222222222",
|
|
||||||
conversationId: "11111111-1111-4111-8111-111111111111",
|
|
||||||
sequence: 1,
|
|
||||||
kind: ConversationEntryKind.UserMessage,
|
|
||||||
visibility: ConversationEntryVisibility.UserVisible,
|
|
||||||
fileId: "44444444-4444-4444-8444-444444444444",
|
|
||||||
payload: {
|
|
||||||
role: "user",
|
|
||||||
parts: [{ type: "text", text: "hello" }],
|
|
||||||
},
|
|
||||||
metadata: {},
|
|
||||||
createdAt: "2026-06-17T09:30:00.000Z",
|
|
||||||
}),
|
|
||||||
).toThrow()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -146,19 +146,6 @@ export const ConversationEntryMetadata = type({
|
|||||||
/** Metadata bag attached to a conversation entry. */
|
/** Metadata bag attached to a conversation entry. */
|
||||||
export type ConversationEntryMetadata = typeof ConversationEntryMetadata.infer
|
export type ConversationEntryMetadata = typeof ConversationEntryMetadata.infer
|
||||||
|
|
||||||
export const ToolCallPayload = type({
|
|
||||||
toolName: "string",
|
|
||||||
})
|
|
||||||
|
|
||||||
export type ToolCallPayload = typeof ToolCallPayload.infer
|
|
||||||
|
|
||||||
export const ToolResultPayload = type({
|
|
||||||
toolName: "string",
|
|
||||||
ok: "boolean",
|
|
||||||
})
|
|
||||||
|
|
||||||
export type ToolResultPayload = typeof ToolResultPayload.infer
|
|
||||||
|
|
||||||
/** Generic object payload used by operational entries. */
|
/** Generic object payload used by operational entries. */
|
||||||
export const GenericObjectPayload = type("Record<string, unknown>")
|
export const GenericObjectPayload = type("Record<string, unknown>")
|
||||||
|
|
||||||
@@ -171,118 +158,4 @@ export type ConversationEntryPayload =
|
|||||||
| AssistantMessagePayload
|
| AssistantMessagePayload
|
||||||
| AttachmentPayload
|
| AttachmentPayload
|
||||||
| ContextSummaryPayload
|
| ContextSummaryPayload
|
||||||
| ToolCallPayload
|
|
||||||
| ToolResultPayload
|
|
||||||
| GenericObjectPayload
|
| GenericObjectPayload
|
||||||
|
|
||||||
export const Conversation = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
updatedAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export type Conversation = typeof Conversation.infer
|
|
||||||
|
|
||||||
export const UserMessageConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'user_message'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: UserMessagePayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const AssistantMessageConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'assistant_message'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: AssistantMessagePayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const AttachmentConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'attachment'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "string.uuid",
|
|
||||||
payload: AttachmentPayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const ToolCallConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'tool_call'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: GenericObjectPayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const ToolResultConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'tool_result'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: GenericObjectPayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const ContextSummaryConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'context_summary'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: ContextSummaryPayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const SystemNoteConversationEntry = type({
|
|
||||||
"+": "reject",
|
|
||||||
id: "string.uuid",
|
|
||||||
conversationId: "string.uuid",
|
|
||||||
sequence: "number.integer >= 1",
|
|
||||||
kind: "'system_note'",
|
|
||||||
visibility: type.enumerated(...Object.values(ConversationEntryVisibility)),
|
|
||||||
fileId: "null",
|
|
||||||
payload: GenericObjectPayload,
|
|
||||||
metadata: ConversationEntryMetadata,
|
|
||||||
createdAt: "string.date.iso",
|
|
||||||
})
|
|
||||||
|
|
||||||
export const ConversationEntry = type.or(
|
|
||||||
UserMessageConversationEntry,
|
|
||||||
AssistantMessageConversationEntry,
|
|
||||||
AttachmentConversationEntry,
|
|
||||||
ToolCallConversationEntry,
|
|
||||||
ToolResultConversationEntry,
|
|
||||||
ContextSummaryConversationEntry,
|
|
||||||
SystemNoteConversationEntry,
|
|
||||||
)
|
|
||||||
|
|
||||||
export type ConversationEntry = typeof ConversationEntry.infer
|
|
||||||
|
|||||||
@@ -10,15 +10,10 @@ export { UnknownActionError } from "./action"
|
|||||||
export type { ConversationEntryPayload } from "./conversation"
|
export type { ConversationEntryPayload } from "./conversation"
|
||||||
export {
|
export {
|
||||||
AssistantMessagePayload,
|
AssistantMessagePayload,
|
||||||
AssistantMessageConversationEntry,
|
|
||||||
AttachmentPayload,
|
AttachmentPayload,
|
||||||
AttachmentConversationEntry,
|
|
||||||
AttachmentType,
|
AttachmentType,
|
||||||
ContextSummary,
|
ContextSummary,
|
||||||
ContextSummaryConversationEntry,
|
|
||||||
ContextSummaryPayload,
|
ContextSummaryPayload,
|
||||||
Conversation,
|
|
||||||
ConversationEntry,
|
|
||||||
ConversationEntryKind,
|
ConversationEntryKind,
|
||||||
ConversationEntryMetadata,
|
ConversationEntryMetadata,
|
||||||
ConversationEntryVisibility,
|
ConversationEntryVisibility,
|
||||||
@@ -26,14 +21,8 @@ export {
|
|||||||
JsonMessagePart,
|
JsonMessagePart,
|
||||||
MessagePart,
|
MessagePart,
|
||||||
ModelRunMetadata,
|
ModelRunMetadata,
|
||||||
SystemNoteConversationEntry,
|
|
||||||
TextMessagePart,
|
TextMessagePart,
|
||||||
ToolCallConversationEntry,
|
|
||||||
ToolCallPayload,
|
|
||||||
ToolResultConversationEntry,
|
|
||||||
ToolResultPayload,
|
|
||||||
UserMessagePayload,
|
UserMessagePayload,
|
||||||
UserMessageConversationEntry,
|
|
||||||
} from "./conversation"
|
} from "./conversation"
|
||||||
|
|
||||||
// Feed
|
// Feed
|
||||||
|
|||||||
Reference in New Issue
Block a user