feat(server-protocol): introduce shared protocol types for AIRI server clients and frontends
- Added package.json for @proj-airi/server-protocol with necessary configurations. - Implemented chat event types including WireMessage, SendMessagesRequest, and PullMessagesRequest. - Defined WebSocket event types and structures for better integration with AIRI components. - Updated server-runtime and server-sdk to utilize the new server-protocol package. - Refactored imports across various packages to replace server-shared types with server-protocol types. - Enhanced type definitions and added TypeScript configurations for better development experience.
This commit is contained in:
@@ -4,17 +4,20 @@ WORKDIR /app
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json tsconfig.json ./
|
||||
COPY patches/ ./patches/
|
||||
COPY apps/server apps/server
|
||||
COPY packages/server-protocol packages/server-protocol
|
||||
COPY packages/server-schema packages/server-schema
|
||||
COPY packages/server-sdk packages/server-sdk
|
||||
COPY packages/plugin-protocol packages/plugin-protocol
|
||||
|
||||
RUN --mount=type=cache,id=pnpm-store,target=/root/.pnpm-store \
|
||||
pnpm install --frozen-lockfile --ignore-scripts
|
||||
|
||||
RUN pnpm -F @proj-airi/server-schema run build
|
||||
RUN pnpm -F @proj-airi/server-sdk run build
|
||||
RUN pnpm -F @proj-airi/server-protocol run build
|
||||
RUN pnpm -F @proj-airi/plugin-protocol run build
|
||||
RUN pnpm -F @proj-airi/server run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
|
||||
@@ -30,10 +30,11 @@ services:
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
server:
|
||||
api:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: apps/server/Dockerfile
|
||||
command: ['pnpm', '-F', '@proj-airi/server', 'run', 'server', 'api']
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@@ -52,6 +53,40 @@ services:
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
outbox-dispatcher:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: apps/server/Dockerfile
|
||||
command: ['pnpm', '-F', '@proj-airi/server', 'run', 'server', 'outbox-dispatcher']
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false
|
||||
- path: .env.local
|
||||
required: false
|
||||
restart: unless-stopped
|
||||
|
||||
cache-sync-consumer:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: apps/server/Dockerfile
|
||||
command: ['pnpm', '-F', '@proj-airi/server', 'run', 'server', 'cache-sync-consumer']
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false
|
||||
- path: .env.local
|
||||
required: false
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
driver: local
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
- WS 广播不具备持久化和重放能力
|
||||
- 真正补齐消息还是靠 `pullMessages`
|
||||
- 广播只是加速客户端同步
|
||||
- 广播只是为了降低拉取延迟,不代表存在旧式 `sync` 端点
|
||||
|
||||
## OpenTelemetry
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"dev": "pnpm run apply:env -- tsx --watch src/bin/run.ts api",
|
||||
"start": "pnpm run apply:env -- tsx src/bin/run.ts api",
|
||||
"server": "pnpm run apply:env -- tsx src/bin/run.ts",
|
||||
"build": "tsc -b",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:push": "pnpm run apply:env -- drizzle-kit push"
|
||||
@@ -37,9 +38,10 @@
|
||||
"@opentelemetry/sdk-trace-node": "^2.6.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.40.0",
|
||||
"@proj-airi/drizzle-orm-browser-migrator": "^0.1.6",
|
||||
"@proj-airi/server-protocol": "workspace:*",
|
||||
"@proj-airi/server-schema": "workspace:*",
|
||||
"@proj-airi/server-sdk": "workspace:",
|
||||
"better-auth": "^1.5.6",
|
||||
"cac": "catalog:",
|
||||
"drizzle-orm": "^0.45.1",
|
||||
"drizzle-valibot": "catalog:",
|
||||
"hono": "catalog:",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { getServerCliHelpText, parseServerRole } from '../run'
|
||||
import { createServerCli, parseServerRole } from '../run'
|
||||
|
||||
describe('server cli', () => {
|
||||
it('parses supported roles', () => {
|
||||
@@ -14,10 +14,13 @@ describe('server cli', () => {
|
||||
expect(parseServerRole(['unknown'])).toBeNull()
|
||||
})
|
||||
|
||||
it('returns help text that lists all supported roles', () => {
|
||||
expect(getServerCliHelpText()).toContain('Usage: server <role>')
|
||||
expect(getServerCliHelpText()).toContain('api')
|
||||
expect(getServerCliHelpText()).toContain('cache-sync-consumer')
|
||||
expect(getServerCliHelpText()).toContain('outbox-dispatcher')
|
||||
it('registers all supported roles with cac', () => {
|
||||
const cli = createServerCli()
|
||||
|
||||
expect(cli.commands.map(command => command.name)).toEqual(expect.arrayContaining([
|
||||
'api',
|
||||
'cache-sync-consumer',
|
||||
'outbox-dispatcher',
|
||||
]))
|
||||
})
|
||||
})
|
||||
|
||||
+40
-24
@@ -5,6 +5,7 @@ import process from 'node:process'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
import { errorMessageFrom } from '@moeru/std'
|
||||
import { cac } from 'cac'
|
||||
|
||||
import { runApiServer } from '../app'
|
||||
import { handleCacheSyncMessage, runBillingEventsConsumer } from './run-billing-events-consumer'
|
||||
@@ -14,26 +15,6 @@ const serverRoles = ['api', 'cache-sync-consumer', 'outbox-dispatcher'] as const
|
||||
|
||||
type ServerRole = typeof serverRoles[number]
|
||||
|
||||
export function getServerCliHelpText(): string {
|
||||
return [
|
||||
'Usage: server <role>',
|
||||
'',
|
||||
'Roles:',
|
||||
' api Start the HTTP/WebSocket API process',
|
||||
' cache-sync-consumer Start the cache-sync Redis Streams consumer',
|
||||
' outbox-dispatcher Publish DB outbox events to Redis Streams',
|
||||
].join('\n')
|
||||
}
|
||||
|
||||
export function parseServerRole(args: string[]): ServerRole | null {
|
||||
const role = args[0]
|
||||
if (!role) {
|
||||
return null
|
||||
}
|
||||
|
||||
return serverRoles.includes(role as ServerRole) ? role as ServerRole : null
|
||||
}
|
||||
|
||||
async function runServerRole(role: ServerRole): Promise<void> {
|
||||
switch (role) {
|
||||
case 'api':
|
||||
@@ -51,15 +32,50 @@ async function runServerRole(role: ServerRole): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const role = parseServerRole(process.argv.slice(2))
|
||||
export function createServerCli() {
|
||||
const cli = cac('server')
|
||||
|
||||
cli
|
||||
.usage('<role>')
|
||||
.command('api', 'Start the HTTP/WebSocket API process')
|
||||
.action(() => runServerRole('api'))
|
||||
|
||||
cli
|
||||
.command('cache-sync-consumer', 'Start the cache-sync Redis Streams consumer')
|
||||
.action(() => runServerRole('cache-sync-consumer'))
|
||||
|
||||
cli
|
||||
.command('outbox-dispatcher', 'Publish DB outbox events to Redis Streams')
|
||||
.action(() => runServerRole('outbox-dispatcher'))
|
||||
|
||||
cli.help()
|
||||
|
||||
return cli
|
||||
}
|
||||
|
||||
export function parseServerRole(args: string[]): ServerRole | null {
|
||||
const cli = createServerCli()
|
||||
cli.parse(['node', 'server', ...args], { run: false })
|
||||
|
||||
const role = cli.matchedCommandName
|
||||
if (!role) {
|
||||
process.stdout.write(`${getServerCliHelpText()}\n`)
|
||||
return null
|
||||
}
|
||||
|
||||
return serverRoles.includes(role as ServerRole) ? role as ServerRole : null
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const cli = createServerCli()
|
||||
cli.parse(process.argv, { run: false })
|
||||
|
||||
if (!cli.matchedCommand) {
|
||||
cli.outputHelp()
|
||||
process.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
await runServerRole(role)
|
||||
await cli.runMatchedCommand()
|
||||
}
|
||||
|
||||
function isExecutedAsMainModule(): boolean {
|
||||
|
||||
@@ -38,7 +38,6 @@ export interface AuthMetrics {
|
||||
}
|
||||
|
||||
export interface EngagementMetrics {
|
||||
chatSync: Counter
|
||||
chatMessages: Counter
|
||||
characterCreated: Counter
|
||||
characterDeleted: Counter
|
||||
@@ -200,11 +199,8 @@ export function initOtel(env: Env): OtelInstance | undefined {
|
||||
|
||||
// Engagement metrics
|
||||
const engagement: EngagementMetrics = {
|
||||
chatSync: meter.createCounter('chat.sync', {
|
||||
description: 'Number of chat sync operations',
|
||||
}),
|
||||
chatMessages: meter.createCounter('chat.messages', {
|
||||
description: 'Number of chat messages synced',
|
||||
description: 'Number of chat messages written or pulled',
|
||||
}),
|
||||
characterCreated: meter.createCounter('character.created', {
|
||||
description: 'Number of characters created',
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { ChatService } from '../services/chats'
|
||||
|
||||
import { useLogger } from '@guiiai/logg'
|
||||
import { defineInvokeHandler } from '@moeru/eventa'
|
||||
import { newMessages, pullMessages, sendMessages } from '@proj-airi/server-sdk'
|
||||
import { newMessages, pullMessages, sendMessages } from '@proj-airi/server-protocol'
|
||||
|
||||
import { createPeerHooks, wsDisconnectedEvent } from '../libs/eventa-hono-adapter'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MessageRole, WireMessage } from '@proj-airi/server-sdk'
|
||||
import type { MessageRole, WireMessage } from '@proj-airi/server-protocol'
|
||||
|
||||
import type { Database } from '../libs/db'
|
||||
import type { EngagementMetrics } from '../libs/otel'
|
||||
@@ -281,7 +281,6 @@ export function createChatService(db: Database, metrics?: EngagementMetrics | nu
|
||||
}
|
||||
})
|
||||
|
||||
metrics?.chatSync.add(1)
|
||||
if (result.totalCount > 0) {
|
||||
metrics?.chatMessages.add(result.totalCount)
|
||||
}
|
||||
|
||||
@@ -8,8 +8,17 @@
|
||||
"ESNext"
|
||||
],
|
||||
"useDefineForClassFields": true,
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"paths": {
|
||||
"@proj-airi/server-protocol": [
|
||||
"../../packages/server-protocol/src/index.ts"
|
||||
],
|
||||
"@proj-airi/server-protocol/*": [
|
||||
"../../packages/server-protocol/src/*"
|
||||
]
|
||||
},
|
||||
"resolveJsonModule": true,
|
||||
"types": [
|
||||
"vitest",
|
||||
@@ -20,6 +29,7 @@
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"../../packages/server-protocol/src/**/*.ts",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
"dependencies": {
|
||||
"@moeru/eventa": "catalog:",
|
||||
"@proj-airi/plugin-protocol": "workspace:*",
|
||||
"@proj-airi/server-shared": "workspace:*",
|
||||
"nanoid": "catalog:",
|
||||
"valibot": "^1.3.1",
|
||||
"xstate": "^5.28.0"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# @proj-airi/server-protocol
|
||||
|
||||
Shared protocol types for AIRI server runtimes, SDKs, and frontend consumers.
|
||||
|
||||
## Usage
|
||||
|
||||
```shell
|
||||
ni @proj-airi/server-protocol -D # from @antfu/ni, can be installed via `npm i -g @antfu/ni`
|
||||
pnpm i @proj-airi/server-protocol -D
|
||||
yarn i @proj-airi/server-protocol -D
|
||||
npm i @proj-airi/server-protocol -D
|
||||
```
|
||||
|
||||
```typescript
|
||||
import type { WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "@proj-airi/server-protocol",
|
||||
"type": "module",
|
||||
"version": "0.9.0-alpha.22",
|
||||
"description": "Shared protocol types for AIRI server clients, frontends, and runtimes",
|
||||
"author": {
|
||||
"name": "Moeru AI Project AIRI Team",
|
||||
"email": "airi@moeru.ai",
|
||||
"url": "https://github.com/moeru-ai"
|
||||
},
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/moeru-ai/airi.git",
|
||||
"directory": "packages/server-protocol"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/types/index.d.mts",
|
||||
"default": "./dist/types/index.mjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.mts",
|
||||
"files": [
|
||||
"README.md",
|
||||
"dist",
|
||||
"package.json"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "pnpm run build",
|
||||
"build": "tsdown",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@moeru/eventa": "catalog:",
|
||||
"@proj-airi/plugin-protocol": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { defineInvokeEventa, defineOutboundEventa } from '@moeru/eventa'
|
||||
|
||||
export interface WireMessage {
|
||||
id: string
|
||||
chatId: string
|
||||
senderId: string | null
|
||||
role: 'system' | 'user' | 'assistant' | 'tool' | 'error'
|
||||
content: string
|
||||
seq: number
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
}
|
||||
|
||||
export type MessageRole = WireMessage['role']
|
||||
|
||||
export interface SendMessagesRequest {
|
||||
chatId: string
|
||||
messages: { id: string, role: string, content: string }[]
|
||||
}
|
||||
|
||||
export interface SendMessagesResponse {
|
||||
seq: number
|
||||
}
|
||||
|
||||
export interface PullMessagesRequest {
|
||||
chatId: string
|
||||
afterSeq: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export interface PullMessagesResponse {
|
||||
messages: WireMessage[]
|
||||
seq: number
|
||||
}
|
||||
|
||||
export interface NewMessagesPayload {
|
||||
chatId: string
|
||||
messages: WireMessage[]
|
||||
fromSeq: number
|
||||
toSeq: number
|
||||
}
|
||||
|
||||
export const sendMessages = defineInvokeEventa<SendMessagesResponse, SendMessagesRequest>('chat:send-messages')
|
||||
export const pullMessages = defineInvokeEventa<PullMessagesResponse, PullMessagesRequest>('chat:pull-messages')
|
||||
export const newMessages = defineOutboundEventa<NewMessagesPayload>('chat:new-messages')
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './events/chat'
|
||||
export * from './types'
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"lib": [
|
||||
"ESNext"
|
||||
],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from 'tsdown'
|
||||
|
||||
export default defineConfig({
|
||||
entry: {
|
||||
'index': 'src/index.ts',
|
||||
'types/index': 'src/types/index.ts',
|
||||
},
|
||||
sourcemap: true,
|
||||
unused: true,
|
||||
inlineOnly: false,
|
||||
})
|
||||
@@ -41,6 +41,7 @@
|
||||
"dependencies": {
|
||||
"@guiiai/logg": "catalog:",
|
||||
"@moeru/std": "catalog:",
|
||||
"@proj-airi/server-protocol": "workspace:^",
|
||||
"@proj-airi/server-shared": "workspace:^",
|
||||
"crossws": "^0.4.4",
|
||||
"h3": "^2.0.1-rc.19",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MetadataEventSource, WebSocketEvent } from '@proj-airi/server-shared/types'
|
||||
import type { MetadataEventSource, WebSocketEvent } from '@proj-airi/server-protocol'
|
||||
|
||||
import type {
|
||||
RouteContext,
|
||||
@@ -11,11 +11,11 @@ import type { AuthenticatedPeer, Peer } from './types'
|
||||
import { timingSafeEqual } from 'node:crypto'
|
||||
|
||||
import { availableLogLevelStrings, Format, LogLevelString, logLevelStringToLogLevelMap, useLogg } from '@guiiai/logg'
|
||||
import { MessageHeartbeat, MessageHeartbeatKind, WebSocketEventSource } from '@proj-airi/server-protocol'
|
||||
import {
|
||||
createInvalidJsonServerErrorMessage,
|
||||
ServerErrorMessages,
|
||||
} from '@proj-airi/server-shared'
|
||||
import { MessageHeartbeat, MessageHeartbeatKind, WebSocketEventSource } from '@proj-airi/server-shared/types'
|
||||
import { defineWebSocketHandler, H3 } from 'h3'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { parse, stringify } from 'superjson'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RouteTargetExpression, WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-shared/types'
|
||||
import type { RouteTargetExpression, WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
|
||||
import type { AuthenticatedPeer } from '../types'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RouteTargetExpression, WebSocketEvent } from '@proj-airi/server-shared/types'
|
||||
import type { RouteTargetExpression, WebSocketEvent } from '@proj-airi/server-protocol'
|
||||
|
||||
import type { AuthenticatedPeer } from '../types'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RouteTargetExpression } from '@proj-airi/server-shared/types'
|
||||
import type { RouteTargetExpression } from '@proj-airi/server-protocol'
|
||||
|
||||
import type { AuthenticatedPeer } from '../../types'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MetadataEventSource } from '@proj-airi/server-shared/types'
|
||||
import type { MetadataEventSource } from '@proj-airi/server-protocol'
|
||||
|
||||
export interface Peer {
|
||||
/**
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"paths": {
|
||||
"@proj-airi/server-shared": [
|
||||
"../server-shared/src/index.ts"
|
||||
"@proj-airi/server-protocol": [
|
||||
"../server-protocol/src/index.ts"
|
||||
],
|
||||
"@proj-airi/server-shared/*": [
|
||||
"../server-shared/src/*"
|
||||
"@proj-airi/server-protocol/*": [
|
||||
"../server-protocol/src/*"
|
||||
]
|
||||
},
|
||||
"esModuleInterop": true,
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"dependencies": {
|
||||
"@moeru/eventa": "catalog:",
|
||||
"@moeru/std": "catalog:",
|
||||
"@proj-airi/server-protocol": "workspace:^",
|
||||
"@proj-airi/server-shared": "workspace:^",
|
||||
"crossws": "^0.4.4",
|
||||
"superjson": "catalog:"
|
||||
|
||||
@@ -6,14 +6,14 @@ import type {
|
||||
WebSocketEvent,
|
||||
WebSocketEventOptionalSource,
|
||||
WebSocketEvents,
|
||||
} from '@proj-airi/server-shared/types'
|
||||
} from '@proj-airi/server-protocol'
|
||||
|
||||
import WebSocket from 'crossws/websocket'
|
||||
import superjson from 'superjson'
|
||||
|
||||
import { errorMessageFrom, sleep } from '@moeru/std'
|
||||
import { MessageHeartbeat, MessageHeartbeatKind } from '@proj-airi/server-protocol'
|
||||
import { isTerminalAuthenticationServerErrorMessage, parseServerErrorMessage } from '@proj-airi/server-shared'
|
||||
import { MessageHeartbeat, MessageHeartbeatKind } from '@proj-airi/server-shared/types'
|
||||
|
||||
export type ClientStatus
|
||||
= | 'idle'
|
||||
|
||||
@@ -1,45 +1 @@
|
||||
import { defineInvokeEventa, defineOutboundEventa } from '@moeru/eventa'
|
||||
|
||||
export interface WireMessage {
|
||||
id: string
|
||||
chatId: string
|
||||
senderId: string | null
|
||||
role: 'system' | 'user' | 'assistant' | 'tool' | 'error'
|
||||
content: string
|
||||
seq: number
|
||||
createdAt: number
|
||||
updatedAt: number
|
||||
}
|
||||
|
||||
export type MessageRole = WireMessage['role']
|
||||
|
||||
export interface SendMessagesRequest {
|
||||
chatId: string
|
||||
messages: { id: string, role: string, content: string }[]
|
||||
}
|
||||
|
||||
export interface SendMessagesResponse {
|
||||
seq: number
|
||||
}
|
||||
|
||||
export interface PullMessagesRequest {
|
||||
chatId: string
|
||||
afterSeq: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export interface PullMessagesResponse {
|
||||
messages: WireMessage[]
|
||||
seq: number
|
||||
}
|
||||
|
||||
export interface NewMessagesPayload {
|
||||
chatId: string
|
||||
messages: WireMessage[]
|
||||
fromSeq: number
|
||||
toSeq: number
|
||||
}
|
||||
|
||||
export const sendMessages = defineInvokeEventa<SendMessagesResponse, SendMessagesRequest>('chat:send-messages')
|
||||
export const pullMessages = defineInvokeEventa<PullMessagesResponse, PullMessagesRequest>('chat:pull-messages')
|
||||
export const newMessages = defineOutboundEventa<NewMessagesPayload>('chat:new-messages')
|
||||
export * from '@proj-airi/server-protocol'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './client'
|
||||
export * from './events/chat'
|
||||
export type * from '@proj-airi/server-shared/types'
|
||||
export { ContextUpdateStrategy, WebSocketEventSource } from '@proj-airi/server-shared/types'
|
||||
export type * from '@proj-airi/server-protocol'
|
||||
export { ContextUpdateStrategy, WebSocketEventSource } from '@proj-airi/server-protocol'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEvent } from '@proj-airi/server-shared/types'
|
||||
import type { WebSocketEvent } from '@proj-airi/server-protocol'
|
||||
|
||||
import superjson from 'superjson'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# @proj-airi/server-shared
|
||||
|
||||
The shared type definitions for all server-side packages of Project AIRI.
|
||||
Server-side shared utilities for AIRI runtimes.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -12,50 +12,9 @@ npm i @proj-airi/server-shared -D
|
||||
```
|
||||
|
||||
```typescript
|
||||
import type { WebSocketEvents } from '@proj-airi/server-shared'
|
||||
import { parseServerErrorMessage } from '@proj-airi/server-shared'
|
||||
```
|
||||
|
||||
## How to use the events in distributed use cases?
|
||||
|
||||
### Scenarios
|
||||
|
||||
#### Minecraft agent
|
||||
|
||||
##### 1. Urgent combat (witch attack)
|
||||
|
||||
- Minecraft sends `spark:notify` (kind=alarm, urgency=immediate, payload hp/location/gear, destinations=["character"]).
|
||||
- Character `spark:emit` working ("Seen it").
|
||||
- Character issues `spark:command` with interrupt=force and options (retreat vs push).
|
||||
- Minecraft `spark:emit` working ("Pillared up; healing") then done/blocked as it executes.
|
||||
- Optional `context:update` for summary/memory.
|
||||
|
||||
##### 2. Prep plan (Ender Dragon)
|
||||
|
||||
- Discord/user intent triggers character `spark:command` to Minecraft (intent=plan, interrupt=soft, steps gather beds/pots/gear, fallback).
|
||||
- Optional `context:update` with tips (lane='game').
|
||||
- Minecraft streams `spark:emit` progress.
|
||||
- If ambushed, Minecraft raises new `spark:notify` (alarm/immediate) to preempt.
|
||||
- Character revises with another `spark:command`.
|
||||
- Completion via `spark:emit` done + summary note.
|
||||
|
||||
##### 3. Routine nudge
|
||||
|
||||
- Minecraft signals low food via `spark:notify` (kind=reminder, urgency=soon, destinations=["character"]).
|
||||
- Character defers to next tick and sends `spark:command` (interrupt=soft, intent=plan: "gather food nearby").
|
||||
- Minecraft `spark:emit` queued/working then done.
|
||||
|
||||
##### 4. Multi-step command while researching (plan + live control)
|
||||
|
||||
> [!NOTE]
|
||||
> Using `intent=plan` keeps the loop alive even with un-finalized ideas—similar to TODO scaffolding in coding agents—while richer guidance is still being researched.
|
||||
|
||||
- Character receives a user goal (e.g., fortify base) and issues an initial `spark:command` to Minecraft (interrupt=soft, intent=plan, steps to gather materials) so the agent keeps working.
|
||||
- Character simultaneously performs memory/search/design tasks outside the game loop (wiki lookup, prior notes).
|
||||
- As insights arrive, character sends `context:update` (lane='game', hints/ideas) to enrich the sub-agent without preemption.
|
||||
- If an urgent event occurs during prep, Minecraft raises `spark:notify` (alarm) → character responds with a short `spark:emit` working and a `spark:command` (interrupt=force) to handle it (e.g., retreat, block up).
|
||||
- Once design is ready, character sends a refined `spark:command` (`intent=proposal` (or `action`), `interrupt=soft`) with structured options/steps/fallbacks.
|
||||
- Minecraft streams `spark:emit` progress; when complete, character summarizes via `spark:emit` or `context:update` for memory.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](../../LICENSE)
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
".": {
|
||||
"types": "./dist/index.d.mts",
|
||||
"default": "./dist/index.mjs"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./dist/types/index.d.mts",
|
||||
"default": "./dist/types/index.mjs"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.mjs",
|
||||
@@ -36,7 +32,5 @@
|
||||
"build": "tsdown",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@proj-airi/plugin-protocol": "workspace:*"
|
||||
}
|
||||
"dependencies": {}
|
||||
}
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
export * from './errors'
|
||||
export * from './types'
|
||||
|
||||
@@ -2,8 +2,7 @@ import { defineConfig } from 'tsdown'
|
||||
|
||||
export default defineConfig({
|
||||
entry: {
|
||||
'index': 'src/index.ts',
|
||||
'types/index': 'src/types/index.ts',
|
||||
index: 'src/index.ts',
|
||||
},
|
||||
sourcemap: true,
|
||||
unused: true,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"@moeru/std": "catalog:",
|
||||
"@proj-airi/ccc": "workspace:*",
|
||||
"@proj-airi/i18n": "workspace:*",
|
||||
"@proj-airi/server-protocol": "workspace:*",
|
||||
"@proj-airi/server-sdk": "workspace:*",
|
||||
"@proj-airi/stage-ui": "workspace:*",
|
||||
"@proj-airi/stage-ui-live2d": "workspace:*",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { Section } from '@proj-airi/stage-ui/components'
|
||||
import { Button, FieldInput, FieldTextArea, SelectTab } from '@proj-airi/ui'
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
|
||||
import type { FlowEntry, PreviewItem } from '../context-flow-types'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
|
||||
type Optional<T> = T | undefined
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
import type { ChatStreamEvent, ContextMessage } from '@proj-airi/stage-ui/types/chat'
|
||||
|
||||
import type { FlowDirection, FlowEntry, SparkNotifyEntryState } from './context-flow-types'
|
||||
|
||||
import { errorMessageFrom } from '@moeru/std'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { useCharacterOrchestratorStore, useCharacterStore } from '@proj-airi/stage-ui/stores/character'
|
||||
import { useChatOrchestratorStore } from '@proj-airi/stage-ui/stores/chat'
|
||||
import { CHAT_STREAM_CHANNEL_NAME, CONTEXT_CHANNEL_NAME } from '@proj-airi/stage-ui/stores/chat/constants'
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
"@proj-airi/i18n": "workspace:^",
|
||||
"@proj-airi/model-driver-lipsync": "workspace:^",
|
||||
"@proj-airi/pipelines-audio": "workspace:^",
|
||||
"@proj-airi/server-protocol": "workspace:^",
|
||||
"@proj-airi/server-sdk": "workspace:^",
|
||||
"@proj-airi/stage-shared": "workspace:^",
|
||||
"@proj-airi/stage-ui-live2d": "workspace:^",
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
import type { ChatProvider, ChatProviderWithExtraOptions, EmbedProvider, EmbedProviderWithExtraOptions, SpeechProvider, SpeechProviderWithExtraOptions, TranscriptionProvider, TranscriptionProviderWithExtraOptions } from '@xsai-ext/providers/utils'
|
||||
import type { Message } from '@xsai/shared-chat'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable style/indent-binary-ops */
|
||||
/* eslint-disable style/operator-linebreak */
|
||||
|
||||
import type { WebSocketEventOf } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEventOf } from '@proj-airi/server-protocol'
|
||||
import type { Store, StoreDefinition } from 'pinia'
|
||||
import type { Mock } from 'vitest'
|
||||
import type { UnwrapRef } from 'vue'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketBaseEvent, WebSocketEventOf, WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEventInputs } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEventInputs } from '@proj-airi/server-protocol'
|
||||
import type { ChatProvider } from '@xsai-ext/providers/utils'
|
||||
import type { CommonContentPart, Message, ToolMessage } from '@xsai/shared-chat'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ContextMessage } from '../../../types/chat'
|
||||
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { nanoid } from 'nanoid'
|
||||
|
||||
const DATETIME_CONTEXT_ID = 'system:datetime'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ContextMessage } from '../../types/chat'
|
||||
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, toRaw } from 'vue'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { WebSocketEvent } from '@proj-airi/server-sdk'
|
||||
import type { WebSocketEvent } from '@proj-airi/server-protocol'
|
||||
|
||||
import { nanoid } from 'nanoid'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { ContextUpdate, InputContextUpdate, WebSocketBaseEvent, WebSocketEvent, WebSocketEventOptionalSource, WebSocketEvents } from '@proj-airi/server-sdk'
|
||||
import type { ContextUpdate, InputContextUpdate, WebSocketBaseEvent, WebSocketEvent, WebSocketEventOptionalSource, WebSocketEvents } from '@proj-airi/server-protocol'
|
||||
import type { CommonContentPart } from '@xsai/shared-chat'
|
||||
|
||||
import { Client, WebSocketEventSource } from '@proj-airi/server-sdk'
|
||||
import { WebSocketEventSource } from '@proj-airi/server-protocol'
|
||||
import { Client } from '@proj-airi/server-sdk'
|
||||
import { isStageTamagotchi, isStageWeb } from '@proj-airi/stage-shared'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { nanoid } from 'nanoid'
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { CommonContentPart } from '@xsai/shared-chat'
|
||||
|
||||
import type { VisionWorkloadId } from '../../../composables/vision/use-vision-workloads'
|
||||
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ContextUpdate, MetadataEventSource, WebSocketEventInputs } from '@proj-airi/server-sdk'
|
||||
import type { ContextUpdate, MetadataEventSource, WebSocketEventInputs } from '@proj-airi/server-protocol'
|
||||
import type { AssistantMessage, CommonContentPart, CompletionToolCall, Message, SystemMessage, ToolMessage, UserMessage } from '@xsai/shared-chat'
|
||||
|
||||
export interface ChatSlicesText {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MetadataEventSource } from '@proj-airi/server-sdk'
|
||||
import type { MetadataEventSource } from '@proj-airi/server-protocol'
|
||||
|
||||
interface EventSourcePayload {
|
||||
source?: string
|
||||
|
||||
Generated
+34
-14
@@ -147,6 +147,9 @@ catalogs:
|
||||
builder-util-runtime:
|
||||
specifier: ^9.5.1
|
||||
version: 9.5.1
|
||||
cac:
|
||||
specifier: ^7.0.0
|
||||
version: 7.0.0
|
||||
capacitor-native-settings:
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0
|
||||
@@ -569,15 +572,18 @@ importers:
|
||||
'@proj-airi/drizzle-orm-browser-migrator':
|
||||
specifier: ^0.1.6
|
||||
version: 0.1.6(drizzle-orm@0.45.1(@electric-sql/pglite@0.4.1)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.8))
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/server-protocol
|
||||
'@proj-airi/server-schema':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/server-schema
|
||||
'@proj-airi/server-sdk':
|
||||
specifier: 'workspace:'
|
||||
version: link:../../packages/server-sdk
|
||||
better-auth:
|
||||
specifier: ^1.5.6
|
||||
version: 1.5.6(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(better-sqlite3@12.5.0)(drizzle-kit@0.31.10)(drizzle-orm@0.45.1(@electric-sql/pglite@0.4.1)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.8))(pg@8.20.0)(react@19.2.3)(vitest@4.1.1)(vue@3.5.30(typescript@5.9.3))
|
||||
cac:
|
||||
specifier: 'catalog:'
|
||||
version: 7.0.0
|
||||
drizzle-orm:
|
||||
specifier: ^0.45.1
|
||||
version: 0.45.1(@electric-sql/pglite@0.4.1)(@opentelemetry/api@1.9.1)(@prisma/client@5.22.0)(@types/pg@8.20.0)(better-sqlite3@12.5.0)(kysely@0.28.14)(pg@8.20.0)(postgres@3.4.8)
|
||||
@@ -2227,9 +2233,6 @@ importers:
|
||||
'@proj-airi/plugin-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../plugin-protocol
|
||||
'@proj-airi/server-shared':
|
||||
specifier: workspace:*
|
||||
version: link:../server-shared
|
||||
nanoid:
|
||||
specifier: 'catalog:'
|
||||
version: 5.1.6
|
||||
@@ -2240,6 +2243,15 @@ importers:
|
||||
specifier: ^5.28.0
|
||||
version: 5.28.0
|
||||
|
||||
packages/server-protocol:
|
||||
dependencies:
|
||||
'@moeru/eventa':
|
||||
specifier: 'catalog:'
|
||||
version: 1.0.0-beta.2(electron@41.0.3)(h3@2.0.1-rc.19(crossws@0.4.4(srvx@0.11.13(patch_hash=c761d25a70e22a0925c88fe91a9dd1c3153dd341d8fd4f260166678156c4df2d))))
|
||||
'@proj-airi/plugin-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../plugin-protocol
|
||||
|
||||
packages/server-runtime:
|
||||
dependencies:
|
||||
'@guiiai/logg':
|
||||
@@ -2248,6 +2260,9 @@ importers:
|
||||
'@moeru/std':
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.0-beta.17
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:^
|
||||
version: link:../server-protocol
|
||||
'@proj-airi/server-shared':
|
||||
specifier: workspace:^
|
||||
version: link:../server-shared
|
||||
@@ -2281,6 +2296,9 @@ importers:
|
||||
'@moeru/std':
|
||||
specifier: 'catalog:'
|
||||
version: 0.1.0-beta.17
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:^
|
||||
version: link:../server-protocol
|
||||
'@proj-airi/server-shared':
|
||||
specifier: workspace:^
|
||||
version: link:../server-shared
|
||||
@@ -2291,11 +2309,7 @@ importers:
|
||||
specifier: 'catalog:'
|
||||
version: 2.2.6
|
||||
|
||||
packages/server-shared:
|
||||
dependencies:
|
||||
'@proj-airi/plugin-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../plugin-protocol
|
||||
packages/server-shared: {}
|
||||
|
||||
packages/stage-layouts:
|
||||
dependencies:
|
||||
@@ -2414,6 +2428,9 @@ importers:
|
||||
'@proj-airi/i18n':
|
||||
specifier: workspace:*
|
||||
version: link:../i18n
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:*
|
||||
version: link:../server-protocol
|
||||
'@proj-airi/server-sdk':
|
||||
specifier: workspace:*
|
||||
version: link:../server-sdk
|
||||
@@ -2593,6 +2610,9 @@ importers:
|
||||
'@proj-airi/pipelines-audio':
|
||||
specifier: workspace:^
|
||||
version: link:../pipelines-audio
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:^
|
||||
version: link:../server-protocol
|
||||
'@proj-airi/server-sdk':
|
||||
specifier: workspace:^
|
||||
version: link:../server-sdk
|
||||
@@ -3333,12 +3353,12 @@ importers:
|
||||
'@proj-airi/audio':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/audio
|
||||
'@proj-airi/server-protocol':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/server-protocol
|
||||
'@proj-airi/server-sdk':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/server-sdk
|
||||
'@proj-airi/server-shared':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/server-shared
|
||||
'@snazzah/davey':
|
||||
specifier: ^0.1.10
|
||||
version: 0.1.10
|
||||
|
||||
+2
-2
@@ -20,14 +20,12 @@ overrides:
|
||||
safer-buffer: npm:@nolyfill/safer-buffer@^1.0.44
|
||||
side-channel: npm:@nolyfill/side-channel@^1.0.44
|
||||
string.prototype.matchall: npm:@nolyfill/string.prototype.matchall@^1.0.44
|
||||
|
||||
patchedDependencies:
|
||||
'@mediapipe/tasks-vision': patches/@mediapipe__tasks-vision.patch
|
||||
mineflayer-pathfinder: patches/mineflayer-pathfinder.patch
|
||||
mineflayer@4.33.0: patches/mineflayer@4.33.0.patch
|
||||
pixi-live2d-display: patches/pixi-live2d-display.patch
|
||||
srvx: patches/srvx.patch
|
||||
|
||||
catalog:
|
||||
'@better-auth/drizzle-adapter': ^1.5.6
|
||||
'@capacitor/android': ^8.2.0
|
||||
@@ -78,6 +76,7 @@ catalog:
|
||||
async-mutex: 0.5.0
|
||||
better-auth: ^1.5.6
|
||||
builder-util-runtime: ^9.5.1
|
||||
cac: ^7.0.0
|
||||
capacitor-native-settings: ^8.1.0
|
||||
crossws: ^0.4.4
|
||||
d3: 7.9.0
|
||||
@@ -155,6 +154,7 @@ onlyBuiltDependencies:
|
||||
- spawn-sync
|
||||
- utf-8-validate
|
||||
- vue-demi
|
||||
|
||||
packageExtensions:
|
||||
'@formkit/auto-animate':
|
||||
peerDependencies:
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
"@guiiai/logg": "catalog:",
|
||||
"@huggingface/transformers": "^3.8.1",
|
||||
"@proj-airi/audio": "workspace:^",
|
||||
"@proj-airi/server-protocol": "workspace:^",
|
||||
"@proj-airi/server-sdk": "workspace:^",
|
||||
"@proj-airi/server-shared": "workspace:^",
|
||||
"@snazzah/davey": "^0.1.10",
|
||||
"@xsai-ext/providers": "catalog:",
|
||||
"@xsai/generate-speech": "catalog:",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { Discord } from '@proj-airi/server-shared/types'
|
||||
import type { Discord } from '@proj-airi/server-protocol'
|
||||
import type { Interaction } from 'discord.js'
|
||||
|
||||
import { env } from 'node:process'
|
||||
|
||||
import { useLogg } from '@guiiai/logg'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-protocol'
|
||||
import { Client as ServerChannel } from '@proj-airi/server-sdk'
|
||||
import { ContextUpdateStrategy } from '@proj-airi/server-shared/types'
|
||||
import { Client, Events, GatewayIntentBits, Partials } from 'discord.js'
|
||||
|
||||
import { handlePing, registerCommands, VoiceManager } from '../bots/discord/commands'
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { Readable } from 'node:stream'
|
||||
|
||||
import type { AudioPlayer, VoiceConnection, VoiceConnectionState } from '@discordjs/voice'
|
||||
import type { Logg } from '@guiiai/logg'
|
||||
import type { Discord } from '@proj-airi/server-protocol'
|
||||
import type { Client as AiriClient } from '@proj-airi/server-sdk'
|
||||
import type { Discord } from '@proj-airi/server-shared/types'
|
||||
import type {
|
||||
BaseGuildVoiceChannel,
|
||||
CacheType,
|
||||
|
||||
Reference in New Issue
Block a user