mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
chore: remove dead UI and agent entrypoints
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
export * from './types';
|
||||
export * from './AgentRegistry';
|
||||
export * from './messageConverter';
|
||||
export * from './permissionAdapter';
|
||||
@@ -1,23 +0,0 @@
|
||||
import { AgentRegistry } from '@/agent/AgentRegistry';
|
||||
import { AcpSdkBackend } from '@/agent/backends/acp';
|
||||
|
||||
function buildEnv(): Record<string, string> {
|
||||
return Object.keys(process.env).reduce((acc, key) => {
|
||||
const value = process.env[key];
|
||||
if (typeof value === 'string') {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
}
|
||||
|
||||
export function registerGeminiAgent(yolo: boolean): void {
|
||||
const args = ['--experimental-acp'];
|
||||
if (yolo) args.push('--yolo');
|
||||
|
||||
AgentRegistry.register('gemini', () => new AcpSdkBackend({
|
||||
command: 'gemini',
|
||||
args,
|
||||
env: buildEnv()
|
||||
}));
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
import { logger } from '@/ui/logger'
|
||||
|
||||
const DEFAULT_OUTBOX_MAX_BYTES = resolveEnvNumber('HAPI_OUTBOX_MAX_BYTES', 16_000_000)
|
||||
const DEFAULT_OUTBOX_MAX_ITEMS = resolveEnvNumber('HAPI_OUTBOX_MAX_ITEMS', 500)
|
||||
const DEFAULT_OUTBOX_MAX_ITEM_BYTES = resolveEnvNumber('HAPI_OUTBOX_MAX_ITEM_BYTES', 1_000_000)
|
||||
const DEFAULT_OUTBOX_MAX_AGE_MS = resolveEnvNumber('HAPI_OUTBOX_MAX_AGE_MS', 15 * 60_000, true)
|
||||
const DEFAULT_DROP_LOG_INTERVAL_MS = resolveEnvNumber('HAPI_OUTBOX_DROP_LOG_INTERVAL_MS', 5_000)
|
||||
|
||||
type OutboxItem = {
|
||||
event: string
|
||||
args: readonly unknown[]
|
||||
sizeBytes: number
|
||||
enqueuedAt: number
|
||||
}
|
||||
|
||||
type SocketOutboxOptions = {
|
||||
maxBytes?: number
|
||||
maxItems?: number
|
||||
maxItemBytes?: number
|
||||
maxAgeMs?: number
|
||||
dropLogIntervalMs?: number
|
||||
}
|
||||
|
||||
function resolveEnvNumber(name: string, fallback: number, allowZero: boolean = false): number {
|
||||
const raw = process.env[name]
|
||||
if (!raw) {
|
||||
return fallback
|
||||
}
|
||||
const parsed = Number.parseInt(raw, 10)
|
||||
if (!Number.isFinite(parsed)) {
|
||||
return fallback
|
||||
}
|
||||
if (parsed < 0) {
|
||||
return fallback
|
||||
}
|
||||
if (parsed === 0 && !allowZero) {
|
||||
return fallback
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
function estimateSizeBytes(payload: unknown): number {
|
||||
try {
|
||||
return Buffer.byteLength(JSON.stringify(payload), 'utf8')
|
||||
} catch {
|
||||
return Number.MAX_SAFE_INTEGER
|
||||
}
|
||||
}
|
||||
|
||||
export class SocketOutbox {
|
||||
private readonly maxBytes: number
|
||||
private readonly maxItems: number
|
||||
private readonly maxItemBytes: number
|
||||
private readonly maxAgeMs: number
|
||||
private readonly dropLogIntervalMs: number
|
||||
private items: OutboxItem[] = []
|
||||
private queuedBytes = 0
|
||||
private droppedCount = 0
|
||||
private droppedBytes = 0
|
||||
private lastDropLogAt = 0
|
||||
private lastDropReason = 'unknown'
|
||||
|
||||
constructor(options?: SocketOutboxOptions) {
|
||||
this.maxBytes = options?.maxBytes ?? DEFAULT_OUTBOX_MAX_BYTES
|
||||
this.maxItems = options?.maxItems ?? DEFAULT_OUTBOX_MAX_ITEMS
|
||||
this.maxItemBytes = options?.maxItemBytes ?? DEFAULT_OUTBOX_MAX_ITEM_BYTES
|
||||
this.maxAgeMs = options?.maxAgeMs ?? DEFAULT_OUTBOX_MAX_AGE_MS
|
||||
this.dropLogIntervalMs = options?.dropLogIntervalMs ?? DEFAULT_DROP_LOG_INTERVAL_MS
|
||||
}
|
||||
|
||||
enqueue(event: string, args: readonly unknown[]): boolean {
|
||||
if (this.maxBytes <= 0 || this.maxItems <= 0) {
|
||||
this.recordDrop('outbox-disabled', 0)
|
||||
return false
|
||||
}
|
||||
|
||||
this.dropExpired()
|
||||
|
||||
const sizeBytes = estimateSizeBytes({ event, args })
|
||||
if (sizeBytes > this.maxItemBytes || sizeBytes > this.maxBytes) {
|
||||
this.recordDrop('item-too-large', sizeBytes)
|
||||
return false
|
||||
}
|
||||
|
||||
while (this.items.length >= this.maxItems || this.queuedBytes + sizeBytes > this.maxBytes) {
|
||||
const removed = this.items.shift()
|
||||
if (!removed) {
|
||||
break
|
||||
}
|
||||
this.queuedBytes -= removed.sizeBytes
|
||||
this.recordDrop('outbox-full', removed.sizeBytes)
|
||||
}
|
||||
|
||||
if (this.items.length >= this.maxItems || this.queuedBytes + sizeBytes > this.maxBytes) {
|
||||
this.recordDrop('outbox-full', sizeBytes)
|
||||
return false
|
||||
}
|
||||
|
||||
this.items.push({
|
||||
event,
|
||||
args,
|
||||
sizeBytes,
|
||||
enqueuedAt: Date.now()
|
||||
})
|
||||
this.queuedBytes += sizeBytes
|
||||
return true
|
||||
}
|
||||
|
||||
flush(emit: (event: string, args: readonly unknown[]) => void): void {
|
||||
this.dropExpired()
|
||||
|
||||
if (this.items.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const items = this.items
|
||||
this.items = []
|
||||
this.queuedBytes = 0
|
||||
|
||||
for (const item of items) {
|
||||
emit(item.event, item.args)
|
||||
}
|
||||
}
|
||||
|
||||
private dropExpired(): void {
|
||||
if (this.maxAgeMs <= 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const cutoff = Date.now() - this.maxAgeMs
|
||||
while (this.items.length > 0 && this.items[0].enqueuedAt < cutoff) {
|
||||
const removed = this.items.shift()
|
||||
if (!removed) {
|
||||
break
|
||||
}
|
||||
this.queuedBytes -= removed.sizeBytes
|
||||
this.recordDrop('expired', removed.sizeBytes)
|
||||
}
|
||||
}
|
||||
|
||||
private recordDrop(reason: string, bytes: number): void {
|
||||
this.droppedCount += 1
|
||||
this.droppedBytes += bytes
|
||||
this.lastDropReason = reason
|
||||
|
||||
const now = Date.now()
|
||||
if (now - this.lastDropLogAt < this.dropLogIntervalMs) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.warn(`[OUTBOX] Dropped ${this.droppedCount} items (${this.droppedBytes} bytes). reason=${this.lastDropReason}`)
|
||||
this.droppedCount = 0
|
||||
this.droppedBytes = 0
|
||||
this.lastDropLogAt = now
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user