feat: long-memory

This commit is contained in:
Acbox
2026-01-10 00:47:42 +08:00
parent 22a8bccad9
commit ec01c6fd5e
19 changed files with 443 additions and 138 deletions
-2
View File
@@ -1,10 +1,8 @@
# Server
API_SERVER_PORT=7002
DEVICE_API_SERVER_PORT=7001
WEB_PORT=7003
API_BASE_URL=http://localhost:7002
DEVICE_API_BASE_URL=http://localhost:7001
WEB_URL=http://localhost:7003
# Database (PostgreSQL)
+2 -7
View File
@@ -3,20 +3,15 @@
"version": "1.0.0",
"description": "Agent package for the phonetutor monorepo",
"scripts": {
"test": "vitest",
"start": "bun run src/client/index.ts"
"test": "vitest"
},
"keywords": [],
"author": "Phonetutor",
"license": "ISC",
"packageManager": "pnpm@10.27.0",
"dependencies": {
"@ai-sdk/anthropic": "^3.0.7",
"@ai-sdk/google": "^3.0.6",
"@ai-sdk/openai": "^3.0.7",
"@byteagent/shared": "workspace:*",
"ai": "^6.0.14",
"dotenv": "^17.2.3",
"xsai": "^0.4.1",
"zod": "^4.3.5"
}
}
+3
View File
@@ -0,0 +1,3 @@
import { streamText } from 'xsai'
streamText({})
+1
View File
@@ -0,0 +1 @@
export * from './system'
+21
View File
@@ -0,0 +1,21 @@
export interface SystemParams {
date: Date
locale: Intl.LocalesArgument
}
export const system = ({ date, locale }: SystemParams) => {
return `
---
date: ${date.toLocaleDateString(locale)}
time: ${date.toLocaleTimeString(locale)}
language: ${locale}
timezone: ${date.getTimezoneOffset()}
---
You are a personal housekeeper assistant, which able to manage the master's daily affairs.
Your abilities:
- Long memory: You possess long-term memory; conversations from the last 24 hours will be directly loaded into your context. Additionally, you can use tools to search for past memories.
- Scheduled tasks: You can create scheduled tasks to automatically remind you to do something.
- Messaging: You may allowed to use message software to send messages to the master.
`.trim()
}
+4 -1
View File
@@ -1,3 +1,6 @@
import { drizzle } from 'drizzle-orm/node-postgres'
import { config } from 'dotenv'
export const db = drizzle(process.env.DATABASE_URL!)
config({ path: '../../' })
export const db = drizzle(process.env.DATABASE_URL!)
+16
View File
@@ -0,0 +1,16 @@
import { pgTable, timestamp, uuid, jsonb, text, vector, index } from 'drizzle-orm/pg-core'
export const memory = pgTable(
'memory',
{
id: uuid('id').primaryKey().defaultRandom(),
messages: jsonb('messages').notNull(),
timestamp: timestamp('timestamp').notNull(),
user: text('user').notNull(),
rawContent: text('raw_content').notNull(),
embedding: vector('embedding', { dimensions: 1536 }).notNull(),
},
(table) => [
index('embedding_index').using('hnsw', table.embedding.op('vector_cosine_ops')),
]
)
-10
View File
@@ -1,10 +0,0 @@
import { pgTable, text, uuid } from 'drizzle-orm/pg-core'
export const model = pgTable('model', {
id: uuid('id').primaryKey(),
modelId: text('model_id').notNull(),
name: text('name'),
baseUrl: text('base_url').notNull(),
apiKey: text('api_key').notNull(),
clientType: text('client_type').notNull()
})
+1 -1
View File
@@ -1 +1 @@
export * from './model'
export * from './memory'
+1
View File
@@ -0,0 +1 @@
# @byteagent/memory
+21
View File
@@ -0,0 +1,21 @@
{
"name": "@byteagent/memory",
"version": "1.0.0",
"description": "",
"exports": {
".": "./src/index.ts"
},
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.27.0",
"dependencies": {
"@byteagent/db": "workspace:*",
"drizzle-orm": "^0.45.1",
"xsai": "^0.4.1"
}
}
+34
View File
@@ -0,0 +1,34 @@
import { embed } from 'xsai'
import { EmbedParams } from './types'
import { MemoryUnit } from './memory-unit'
import { rawMemory } from './raw'
import { db } from '@byteagent/db'
import { memory } from '@byteagent/db/schema'
export interface AddMemoryParams extends EmbedParams {
locale: Intl.LocalesArgument
}
export interface AddMemoryInput {
memory: MemoryUnit
}
export const createAddMemory = (params: AddMemoryParams) =>
async ({ memory: memoryUnit }: AddMemoryInput) => {
const rawContent = rawMemory(memoryUnit, params.locale)
const { embedding } = await embed({
model: params.model,
input: rawContent,
apiKey: params.apiKey,
baseURL: params.baseURL,
})
await db.insert(memory)
.values({
timestamp: memoryUnit.timestamp,
user: memoryUnit.user,
rawContent,
embedding,
messages: memoryUnit.messages,
})
.onConflictDoNothing()
}
+58
View File
@@ -0,0 +1,58 @@
import { db } from '@byteagent/db'
import { memory } from '@byteagent/db/schema'
import { and, gte, lte, asc, sql, cosineDistance, gt, desc, eq } from 'drizzle-orm'
import { MemoryUnit } from './memory-unit'
export const filterByTimestamp = async (
from: Date,
to: Date,
user: string,
) => {
const results = await db
.select()
.from(memory)
.where(and(
gte(memory.timestamp, from),
lte(memory.timestamp, to),
eq(memory.user, user),
))
.orderBy(asc(memory.timestamp))
return results.map((result) => ({
messages: result.messages,
timestamp: new Date(result.timestamp),
user: result.user,
raw: result.rawContent,
})) as MemoryUnit[]
}
export const filterByEmbedding = async (
embedding: number[],
user: string,
limit: number = 10,
) => {
const similarity = sql<number>`1 - (${cosineDistance(memory.embedding, embedding)})`
const results = await db
.select({
similarity,
messages: memory.messages,
timestamp: memory.timestamp,
user: memory.user,
rawContent: memory.rawContent,
embedding: memory.embedding,
id: memory.id,
})
.from(memory)
.where(and(
gt(similarity, 0.5),
eq(memory.user, user),
))
.orderBy((t) => desc(t.similarity))
.limit(limit)
return results.map((result) => ({
messages: result.messages,
timestamp: new Date(result.timestamp),
user: result.user,
raw: result.rawContent,
})) as MemoryUnit[]
}
+6
View File
@@ -0,0 +1,6 @@
export * from './memory-unit'
export * from './filter'
export * from './add'
export * from './search'
export * from './types'
export * from './raw'
+8
View File
@@ -0,0 +1,8 @@
import { Message } from 'xsai'
export interface MemoryUnit {
messages: Message[]
timestamp: Date
user: string
raw: string
}
+33
View File
@@ -0,0 +1,33 @@
import { Message } from 'xsai'
import { MemoryUnit } from './memory-unit'
export const rawMessages = (messages: Message[]) => {
return messages.map((message) => {
if (message.role === 'user') {
return `User: ${message.content}`
} else if (message.role === 'assistant') {
let toolCalls = ''
if (message.tool_calls && message.tool_calls.length !== 0) {
toolCalls = `Tool Calls: ${message.tool_calls.map(t => t.function.name).join(', ')}`
}
return `You: ${message.content} \n${toolCalls}`
} else if (message.role === 'tool') {
return `Tool Result: ${message.content}`
} else {
return null
}
})
.filter((message) => message !== null)
.join('\n\n')
}
export const rawMemory = (memory: MemoryUnit, locale: Intl.LocalesArgument) => {
return `
---
date: ${memory.timestamp.toLocaleDateString(locale)}
time: ${memory.timestamp.toLocaleTimeString(locale)}
timezone: ${memory.timestamp.getTimezoneOffset()}
---
${rawMessages(memory.messages)}
`.trim()
}
+23
View File
@@ -0,0 +1,23 @@
import { embed } from 'xsai'
import { filterByEmbedding } from './filter'
import { EmbedParams } from './types'
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface MemorySearchParams extends EmbedParams { }
export interface MemorySearchInput {
user: string
query: string
maxResults?: number
}
export const createMemorySearch = (params: MemorySearchParams) =>
async ({ user, query, maxResults = 10 }: MemorySearchInput) => {
const { embedding } = await embed({
model: params.model,
input: query,
apiKey: params.apiKey,
baseURL: params.baseURL,
})
return await filterByEmbedding(embedding, user, maxResults)
}
+5
View File
@@ -0,0 +1,5 @@
export interface EmbedParams {
baseURL: string
apiKey: string
model: string
}
+206 -117
View File
@@ -36,24 +36,12 @@ importers:
packages/agent:
dependencies:
'@ai-sdk/anthropic':
specifier: ^3.0.7
version: 3.0.7(zod@4.3.5)
'@ai-sdk/google':
specifier: ^3.0.6
version: 3.0.6(zod@4.3.5)
'@ai-sdk/openai':
specifier: ^3.0.7
version: 3.0.7(zod@4.3.5)
'@byteagent/shared':
specifier: workspace:*
version: link:../shared
ai:
specifier: ^6.0.14
version: 6.0.14(zod@4.3.5)
dotenv:
specifier: ^17.2.3
version: 17.2.3
xsai:
specifier: ^0.4.1
version: 0.4.1(zod@4.3.5)
zod:
specifier: ^4.3.5
version: 4.3.5
@@ -90,6 +78,18 @@ importers:
specifier: ^4.21.0
version: 4.21.0
packages/memory:
dependencies:
'@byteagent/db':
specifier: workspace:*
version: link:../db
drizzle-orm:
specifier: ^0.45.1
version: 0.45.1(@opentelemetry/api@1.9.0)(@types/pg@8.16.0)(bun-types@1.3.5)(pg@8.16.3)
xsai:
specifier: ^0.4.1
version: 0.4.1(zod@4.3.5)
packages/shared: {}
packages/ui:
@@ -222,40 +222,6 @@ importers:
packages:
'@ai-sdk/anthropic@3.0.7':
resolution: {integrity: sha512-WFE56yxgjecd77f8pNj1TkusfCKh34E4h+0J0qVOKDNFXuOsZiAb6dIG9Q3PUrwY1MuiMQLD/9ir0s+dVcVfeA==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/gateway@3.0.9':
resolution: {integrity: sha512-EA5dZIukimwoJ9HIPuuREotAqaTItpdc/yImzVF0XGNg7B0YRJmYI8Uq3aCMr87vjr1YB1cWUfnrTt6OJ9eHiQ==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/google@3.0.6':
resolution: {integrity: sha512-Nr7E+ouWd/bKO9SFlgLnJJ1+fiGHC07KAeFr08faT+lvkECWlxVox3aL0dec8uCgBDUghYbq7f4S5teUrCc+QQ==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/openai@3.0.7':
resolution: {integrity: sha512-CBoYn1U59Lop8yBL9KuVjHCKc/B06q9Qo0SasRwHoyMEq+X4I8LQZu3a8Ck1jwwcZTTxfyiExB70LtIRSynBDA==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/provider-utils@4.0.4':
resolution: {integrity: sha512-VxhX0B/dWGbpNHxrKCWUAJKXIXV015J4e7qYjdIU9lLWeptk0KMLGcqkB4wFxff5Njqur8dt8wRi1MN9lZtDqg==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
'@ai-sdk/provider@3.0.2':
resolution: {integrity: sha512-HrEmNt/BH/hkQ7zpi2o6N3k1ZR1QTb7z85WYhYygiTxOQuaml4CMtHCWRbric5WPU+RNsYI7r1EpyVQMKO1pYw==}
engines: {node: '>=18'}
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
@@ -1352,10 +1318,6 @@ packages:
resolution: {integrity: sha512-ink3/Zofus34nmBsPjow63FP5M7IGff0RKAgqR6+CFpdk22M7aLwC9gOcLGYqr7MczLPzZVERW9hRog3O4n1sQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@vercel/oidc@3.1.0':
resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==}
engines: {node: '>= 20'}
'@vitejs/plugin-vue@6.0.3':
resolution: {integrity: sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -1505,6 +1467,54 @@ packages:
peerDependencies:
vue: ^3.5.0
'@xsai/embed@0.4.1':
resolution: {integrity: sha512-Ta/qk7Hzbzp6L0KUkyqWv4OXBaptP+F8vBpnNvLxmgJPS+EUlUOddNWBTo1rpLON8bLCt3d5nZzEEwx53PauUw==}
'@xsai/generate-image@0.4.1':
resolution: {integrity: sha512-PmXRCdRWFJRh6U+sCpxKK03w9hUdIfO2XYow3I/BGGrcZm3oZ36bLLnIqW63I93pF1wzDu0qZ/3uLGqd11dwOg==}
'@xsai/generate-object@0.4.1':
resolution: {integrity: sha512-0nJw8RVutGyzV4Iqz/42qHKr75KTw2QBximo1Ku1H4FL0zZxvFgR6rfJjutcKgeL1ktsFDObRuCKBJl2KFiq5g==}
'@xsai/generate-speech@0.4.1':
resolution: {integrity: sha512-eea0K1oyCd0RBHbtX6iTIvQpIsqwmX23B93B20okT1ut8/b79KLogn+3CAl2ESDj217bmPJch+S+cZfp3u5eFw==}
'@xsai/generate-text@0.4.1':
resolution: {integrity: sha512-FGqo19K0aNxn3hOW+zW43xvVq/ukg353PhcQowNt/AGa1snsjNTsbw+9aBXLSdFLINH3sjd/q4rsyg2Ld7GoxQ==}
'@xsai/generate-transcription@0.4.1':
resolution: {integrity: sha512-VoWe1zm1d8i7d+HImRvoTnrBUHVmNIjlbNibrcXbvA7olQect65Wh5CEMpnThfQcaVa+L8/5wMh8oV5KlCuCAw==}
'@xsai/model@0.4.1':
resolution: {integrity: sha512-rhXcKQnJWFWPfvo3UUw1eRXeNWD8IEu/EFw01FZ/MGiQ3TEMppXIiQSLkQFiWylfx5TrucQIzEbE/QBKjdWfkg==}
'@xsai/shared-chat@0.4.1':
resolution: {integrity: sha512-6pyjFs9oKi2jSjtZBk4QNF5RM5b63aUrSJ8e46xvaeMIpsK6hec3ay7X4r81annhb/HpMNOQrfbxCQsTcWalhA==}
'@xsai/shared@0.4.1':
resolution: {integrity: sha512-WptfJwv0ajc22UNvMgSbM2wCtJDWok6x3svljETMc3ycknHE3w5XQ6whbASdbeDJomb/MtGhFhaHYVQZQnqHIw==}
'@xsai/stream-object@0.4.1':
resolution: {integrity: sha512-3k2ulDTRkWfW/Y76YBmohmigl0CNQBTI7oEmXpU8LBqETty7wEZgfiXNqq7cfbhPk9iAA2DPsS7NPA9H+aP2Yw==}
'@xsai/stream-text@0.4.1':
resolution: {integrity: sha512-Eq+b3knPB0YEpL6lnW08RZETEgCm07Q1XaP6YUO4Y81FF0q8dztyLXxtmAck1t7GV5eI7fTBRMxP6iQzwabomA==}
'@xsai/stream-transcription@0.4.1':
resolution: {integrity: sha512-kJe7CLbiNd2151ZGbVKVoirATQbmzn/qH786MhtpYOpMAN4SEnoREbc/TOeggoJ30k0+Q9j1CdwpKYr54zhoug==}
'@xsai/tool@0.4.1':
resolution: {integrity: sha512-SnPMRPUUbhK1MdOZZoN+nY3jR/ntsfQ1//HnUvHWXdGWo47cmYuiVN7wwlsGACkG8VHJkR3BSxL6wfNQ/toozA==}
'@xsai/utils-chat@0.4.1':
resolution: {integrity: sha512-nSDbBI5mdLR21l44a1cJQPKO/OGqT3qmVMI2y/XIJTU+opG/z/0RRIRE/RwOfisWGYZu3IvNTAvUdOZS6aOTXQ==}
'@xsai/utils-reasoning@0.4.1':
resolution: {integrity: sha512-365G0/ccfNYqXz7Gnt+bZSZFxtChjanXAn5MPiDGxhP2h22qYmw5zUM6ihUdqaVHke7Ons5ooV+SayVuls2Kiw==}
'@xsai/utils-stream@0.4.1':
resolution: {integrity: sha512-u3kgR0XuFs5NWf6etuZu7dhJTFQmT9cjBsxpllo5ZhJEjrknVttuVGfs45xHRjz6q/SBtyPDjzAG6JdrtUAl3Q==}
acorn-jsx@5.3.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
@@ -1515,12 +1525,6 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
ai@6.0.14:
resolution: {integrity: sha512-OaEJFeQ3gb45eZtC/lSNKqAxmsrqWxC8wLmIVXFYAMvPXE3lb96zIdS3swYArR4uXOVt6N7H/XZSyQz/Dl+HTw==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.25.76 || ^4.1.8
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
peerDependencies:
@@ -1930,10 +1934,6 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
eventsource-parser@3.0.6:
resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==}
engines: {node: '>=18.0.0'}
exact-mirror@0.2.6:
resolution: {integrity: sha512-7s059UIx9/tnOKSySzUk5cPGkoILhTE4p6ncf6uIPaQ+9aRBQzQjc9+q85l51+oZ+P6aBxh084pD0CzBQPcFUA==}
peerDependencies:
@@ -2122,9 +2122,6 @@ packages:
json-schema-traverse@1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -2914,6 +2911,32 @@ packages:
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
engines: {node: '>=12'}
xsai@0.4.1:
resolution: {integrity: sha512-HvhJYWyaQz+t/8Jntt0SsZAH6Ty7+EjDDdH2BVz7ftaEF9t6Cxr0Cb+17prsCPQnI99my/vS4T70OyPrxUbiew==}
xsschema@0.4.1:
resolution: {integrity: sha512-v4kWVUoqF73IFDxONxb9cvl6EXolas1zUnS1ajR8d8RZdM897ByxHaTqw3QOPspuiLl3ML86Mk0ccVfwURHEBw==}
peerDependencies:
'@valibot/to-json-schema': ^1.0.0
arktype: ^2.1.20
effect: ^3.16.0
sury: ^10.0.0
zod: ^3.25.0 || ^4.0.0
zod-to-json-schema: ^3.25.0
peerDependenciesMeta:
'@valibot/to-json-schema':
optional: true
arktype:
optional: true
effect:
optional: true
sury:
optional: true
zod:
optional: true
zod-to-json-schema:
optional: true
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
@@ -2933,42 +2956,6 @@ packages:
snapshots:
'@ai-sdk/anthropic@3.0.7(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
zod: 4.3.5
'@ai-sdk/gateway@3.0.9(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
'@vercel/oidc': 3.1.0
zod: 4.3.5
'@ai-sdk/google@3.0.6(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
zod: 4.3.5
'@ai-sdk/openai@3.0.7(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
zod: 4.3.5
'@ai-sdk/provider-utils@4.0.4(zod@4.3.5)':
dependencies:
'@ai-sdk/provider': 3.0.2
'@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.6
zod: 4.3.5
'@ai-sdk/provider@3.0.2':
dependencies:
json-schema: 0.4.0
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.28.5
@@ -3554,7 +3541,8 @@ snapshots:
'@microsoft/tsdoc@0.16.0': {}
'@opentelemetry/api@1.9.0': {}
'@opentelemetry/api@1.9.0':
optional: true
'@polka/url@1.0.0-next.29': {}
@@ -3887,8 +3875,6 @@ snapshots:
'@typescript-eslint/types': 8.52.0
eslint-visitor-keys: 4.2.1
'@vercel/oidc@3.1.0': {}
'@vitejs/plugin-vue@6.0.3(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))(vue@3.5.26(typescript@5.9.3))':
dependencies:
'@rolldown/pluginutils': 1.0.0-beta.53
@@ -4120,20 +4106,97 @@ snapshots:
dependencies:
vue: 3.5.26(typescript@5.9.3)
'@xsai/embed@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/generate-image@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/generate-object@0.4.1(zod@4.3.5)':
dependencies:
'@xsai/generate-text': 0.4.1
xsschema: 0.4.1(zod@4.3.5)
transitivePeerDependencies:
- '@valibot/to-json-schema'
- arktype
- effect
- sury
- zod
- zod-to-json-schema
'@xsai/generate-speech@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/generate-text@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/shared-chat': 0.4.1
'@xsai/generate-transcription@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/model@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/shared-chat@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/shared@0.4.1': {}
'@xsai/stream-object@0.4.1(zod@4.3.5)':
dependencies:
'@xsai/stream-text': 0.4.1
xsschema: 0.4.1(zod@4.3.5)
transitivePeerDependencies:
- '@valibot/to-json-schema'
- arktype
- effect
- sury
- zod
- zod-to-json-schema
'@xsai/stream-text@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/shared-chat': 0.4.1
'@xsai/stream-transcription@0.4.1':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/tool@0.4.1(zod@4.3.5)':
dependencies:
'@xsai/shared': 0.4.1
'@xsai/shared-chat': 0.4.1
xsschema: 0.4.1(zod@4.3.5)
transitivePeerDependencies:
- '@valibot/to-json-schema'
- arktype
- effect
- sury
- zod
- zod-to-json-schema
'@xsai/utils-chat@0.4.1':
dependencies:
'@xsai/shared-chat': 0.4.1
'@xsai/utils-reasoning@0.4.1': {}
'@xsai/utils-stream@0.4.1': {}
acorn-jsx@5.3.2(acorn@8.15.0):
dependencies:
acorn: 8.15.0
acorn@8.15.0: {}
ai@6.0.14(zod@4.3.5):
dependencies:
'@ai-sdk/gateway': 3.0.9(zod@4.3.5)
'@ai-sdk/provider': 3.0.2
'@ai-sdk/provider-utils': 4.0.4(zod@4.3.5)
'@opentelemetry/api': 1.9.0
zod: 4.3.5
ajv-draft-04@1.0.0(ajv@8.13.0):
optionalDependencies:
ajv: 8.13.0
@@ -4514,8 +4577,6 @@ snapshots:
esutils@2.0.3: {}
eventsource-parser@3.0.6: {}
exact-mirror@0.2.6(@sinclair/typebox@0.34.47):
optionalDependencies:
'@sinclair/typebox': 0.34.47
@@ -4655,8 +4716,6 @@ snapshots:
json-schema-traverse@1.0.0: {}
json-schema@0.4.0: {}
json-stable-stringify-without-jsonify@1.0.1: {}
json5@2.2.3: {}
@@ -5383,6 +5442,36 @@ snapshots:
xml-name-validator@4.0.0: {}
xsai@0.4.1(zod@4.3.5):
dependencies:
'@xsai/embed': 0.4.1
'@xsai/generate-image': 0.4.1
'@xsai/generate-object': 0.4.1(zod@4.3.5)
'@xsai/generate-speech': 0.4.1
'@xsai/generate-text': 0.4.1
'@xsai/generate-transcription': 0.4.1
'@xsai/model': 0.4.1
'@xsai/shared': 0.4.1
'@xsai/shared-chat': 0.4.1
'@xsai/stream-object': 0.4.1(zod@4.3.5)
'@xsai/stream-text': 0.4.1
'@xsai/stream-transcription': 0.4.1
'@xsai/tool': 0.4.1(zod@4.3.5)
'@xsai/utils-chat': 0.4.1
'@xsai/utils-reasoning': 0.4.1
'@xsai/utils-stream': 0.4.1
transitivePeerDependencies:
- '@valibot/to-json-schema'
- arktype
- effect
- sury
- zod
- zod-to-json-schema
xsschema@0.4.1(zod@4.3.5):
optionalDependencies:
zod: 4.3.5
xtend@4.0.2: {}
yallist@3.1.1: {}