@ghuri/agents 0.0.0-stage → 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +458 -2
- package/dist/index.d.ts +871 -0
- package/dist/index.js +1995 -0
- package/dist/index.js.map +1 -0
- package/package.json +98 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/agent.ts","../src/memory.ts","../src/errors.ts","../src/models.ts","../src/providers.ts","../src/settings.ts","../src/queue.ts","../src/tools/execute.ts","../src/tools/tool.ts","../src/tools/schema.ts","../src/tools/types.ts","../src/apps.ts","../src/migrations/index.ts","../src/migrations/0001_initial.ts","../src/http.ts","../src/mcp.ts","../src/tools/model.ts","../src/tools/viewset.ts","../src/tools/router.ts"],"sourcesContent":["import {\n anonymousUser,\n type GhuriContext,\n ImproperlyConfigured,\n type RequestUser,\n tryGetContext,\n} from '@ghuri/core'\nimport type { APIRequest, PermissionClass } from '@ghuri/rest'\nimport { NotAuthenticated, PermissionDenied } from '@ghuri/rest'\nimport {\n tool as aiTool,\n createUIMessageStreamResponse,\n generateText,\n type JSONSchema7,\n jsonSchema,\n type LanguageModel,\n type LanguageModelUsage,\n type ModelMessage,\n type StreamTextResult,\n stepCountIs,\n streamText,\n type ToolSet,\n type UIMessageChunk,\n} from 'ai'\nimport {\n ConversationNotFound,\n createConversation,\n getConversation,\n loadMessages,\n memoryAvailable,\n saveMessages,\n titleFrom,\n} from './memory'\nimport type { Conversation } from './models'\nimport { resolveModel } from './providers'\nimport { type EnqueueOptions, enqueueRun } from './queue'\nimport { agentsSettings, DEFAULT_MAX_STEPS, defaultPermissionClasses } from './settings'\nimport { inContext, toToolError } from './tools/execute'\nimport { collectDeclaredTools, isToolDecorator, standaloneTool, type ToolDecorator } from './tools/tool'\nimport { type AgentTool, isAgentTool, isToolkit, type ToolContext, type Toolkit } from './tools/types'\n\n/** What can go in an agent's `tools`: toolkits, standalone `tool({...execute})`s and `AgentTool`s. */\nexport type ToolEntry = Toolkit | ToolDecorator | AgentTool\nexport type ToolsInput = ToolEntry[] | Record<string, ToolEntry>\n\n/** Input of a run: a user message, or AI SDK model messages to append. */\nexport type AgentInput = string | ModelMessage[]\n\nexport interface RunOptions {\n /** The user the agent acts for; every tool runs with this user's permissions (default: anonymous). */\n user?: RequestUser | null\n /** Continue a stored conversation (must belong to `user` and this agent). */\n conversationId?: string | null\n signal?: AbortSignal\n /** Load / save conversation memory (default: when the `agents` app is installed and `agent.memory`). */\n memory?: boolean\n /** Check the agent's `permissionClasses` for `user` first (HTTP and MCP always do). */\n checkPermissions?: boolean\n /** The REST request when running for an HTTP / MCP call. */\n request?: APIRequest\n /** Free-form values available to `instructions(ctx)` and hooks as `ctx.extra`. */\n context?: Record<string, unknown>\n /** Title for a new conversation (default: from the first message). */\n title?: string\n}\n\n/** Per-run state passed to `instructions(ctx)` and the hooks. */\nexport interface AgentRunContext {\n agent: Agent\n agentName: string\n user: RequestUser\n input: AgentInput\n conversationId?: string\n conversation?: Conversation\n /** Full prompt: stored history + the new messages. Hooks may edit it. */\n messages: ModelMessage[]\n /** The new messages of this run (saved to memory with the response). */\n newMessages: ModelMessage[]\n signal?: AbortSignal\n request?: APIRequest\n extra: Record<string, unknown>\n}\n\n/** A tool call made during a run. */\nexport interface ToolCallRecord {\n toolCallId: string\n toolName: string\n input: unknown\n output?: unknown\n /** Error message returned to the model (permission denied, validation…). */\n error?: string\n}\n\nexport interface AgentRunResult {\n text: string\n /** Messages added by this run: the input and the response (assistant / tool messages). */\n messages: ModelMessage[]\n toolCalls: ToolCallRecord[]\n usage: LanguageModelUsage\n finishReason: string\n steps: number\n conversationId?: string\n}\n\n/** Passed to `onToolCall` before a tool runs. Throw (e.g. `ToolError`) to refuse the call. */\nexport interface ToolCallInfo {\n toolName: string\n toolCallId?: string\n input: unknown\n}\n\ninterface Prepared {\n ctx: AgentRunContext\n model: LanguageModel\n instructions?: string\n tools: ToolSet\n ghuri?: GhuriContext\n}\n\nfunction deriveName(cls: Function): string {\n const base = cls.name.replace(/Agent$/, '') || cls.name || 'agent'\n return base\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[^A-Za-z0-9_-]+/g, '-')\n .toLowerCase()\n}\n\nfunction errorText(error: unknown): string {\n if (error instanceof Error) return error.message\n return typeof error === 'string' ? error : JSON.stringify(error)\n}\n\nfunction toolCallsFrom(content: ReadonlyArray<any>): ToolCallRecord[] {\n const calls = new Map<string, ToolCallRecord>()\n for (const part of content) {\n if (part.type === 'tool-call') {\n calls.set(part.toolCallId, { toolCallId: part.toolCallId, toolName: part.toolName, input: part.input })\n } else if (part.type === 'tool-result' || part.type === 'tool-error') {\n const rec: ToolCallRecord = calls.get(part.toolCallId) ?? {\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n input: part.input,\n }\n if (part.type === 'tool-result') rec.output = part.output\n else rec.error = errorText(part.error)\n calls.set(part.toolCallId, rec)\n }\n }\n return [...calls.values()]\n}\n\n/**\n * An LLM agent with tools that run as the requesting user.\n *\n * ```ts\n * export class SupportAgent extends Agent {\n * model = 'workers-ai:@cf/meta/llama-3.3-70b-instruct-fp8-fast'\n * instructions = 'You help customers with their orders.'\n * tools = [new ModelTools(Order, { actions: ['list', 'retrieve'], filter: (qs, user) => qs.filter({ customer: user.pk }) })]\n * permissionClasses = [IsAuthenticated]\n *\n * @tool({ description: 'Refund an order', input: z.object({ orderId: z.number() }) })\n * async refund({ orderId }, { user }) { ... }\n * }\n * const { text, conversationId } = await new SupportAgent().run('Where is my order?', { user })\n * ```\n */\nexport class Agent {\n /** Name used for conversations, URLs and MCP (`ask_<name>`); default: class name minus `Agent`, kebab-case. */\n static agentName?: string\n /** Shown to MCP clients for the `ask_<name>` tool. */\n static description?: string\n /** Tools implemented by methods of the same name, without decorators: `{ refund: tool({...}) }`. */\n static tools?: Record<string, ToolDecorator>\n\n /** `'provider:model-id'` or an AI SDK `LanguageModel` (default `AGENTS.DEFAULT_MODEL`). */\n model?: string | LanguageModel\n /** System instructions, or a function of the run context. */\n instructions?: string | ((ctx: AgentRunContext) => string | Promise<string>)\n /** Toolkits and tools (plus `@tool` methods and `static tools`). */\n tools?: ToolsInput\n /** REST permission classes checked for HTTP / MCP access (default `AGENTS.PERMISSION_CLASSES`). */\n permissionClasses?: PermissionClass[]\n /** Maximum model steps (tool round trips) per run (default `AGENTS.MAX_STEPS`, 10). */\n maxSteps?: number\n temperature?: number\n maxOutputTokens?: number\n /** Provider-specific options passed to the AI SDK (`{ anthropic: { thinking: … } }`). */\n providerOptions?: Record<string, any>\n /** Use conversation memory when the `agents` app is installed (default true). */\n memory = true\n /** Set by `AgentRouter.register(name, …)`. */\n agentName?: string\n\n /** Called before the model runs; may edit `ctx.messages`. Throw to abort the run. */\n beforeRun?(ctx: AgentRunContext): void | Promise<void>\n /** Called after a run finished and was saved. */\n afterRun?(result: AgentRunResult, ctx: AgentRunContext): void | Promise<void>\n /** Called before every tool call. Throw (e.g. `ToolError`) to refuse it; the model sees the error. */\n onToolCall?(call: ToolCallInfo, ctx: AgentRunContext): void | Promise<void>\n\n /** `new this().run(input, opts)`. */\n static run<T extends Agent>(\n this: new () => T,\n input: AgentInput,\n opts?: RunOptions,\n ): Promise<AgentRunResult> {\n return new this().run(input, opts)\n }\n\n getName(): string {\n const cls = this.constructor as typeof Agent\n return this.agentName ?? (Object.hasOwn(cls, 'agentName') ? cls.agentName : undefined) ?? deriveName(cls)\n }\n\n getDescription(): string {\n const cls = this.constructor as typeof Agent\n return cls.description ?? `Ask the ${this.getName()} agent. It answers in natural language.`\n }\n\n getPermissionClasses(): PermissionClass[] {\n return this.permissionClasses ?? defaultPermissionClasses()\n }\n\n /** System instructions for a run (override for dynamic instructions). */\n async getInstructions(ctx: AgentRunContext): Promise<string | undefined> {\n const i = this.instructions\n return typeof i === 'function' ? await i.call(this, ctx) : i\n }\n\n /** All tools of this agent, normalized (toolkits expanded, declared methods bound). */\n getTools(): AgentTool[] {\n const out: AgentTool[] = []\n const add = (entry: unknown, key?: string) => {\n if (isToolDecorator(entry)) out.push(standaloneTool(entry, key))\n else if (isAgentTool(entry)) out.push(key && !entry.name ? { ...entry, name: key } : entry)\n else if (isToolkit(entry)) out.push(...entry.getTools())\n else\n throw new ImproperlyConfigured(\n `${this.constructor.name}.tools: unsupported entry ${key ? `'${key}'` : String(entry)} (use toolkits, tool({...}) or AgentTool objects).`,\n )\n }\n const tools = this.tools\n if (Array.isArray(tools)) for (const t of tools) add(t)\n else if (tools && typeof tools === 'object') for (const [k, t] of Object.entries(tools)) add(t, k)\n out.push(...collectDeclaredTools(this))\n const seen = new Set<string>()\n for (const t of out) {\n if (seen.has(t.name))\n throw new ImproperlyConfigured(`${this.constructor.name} has two tools named '${t.name}'.`)\n seen.add(t.name)\n }\n return out\n }\n\n /** Check `permissionClasses` for `user` (`NotAuthenticated` / `PermissionDenied` from `@ghuri/rest`). */\n async checkPermissions(user: RequestUser, request?: APIRequest): Promise<void> {\n const req: any = request ?? { user, auth: null, method: 'POST', successfulAuthenticator: null }\n for (const P of this.getPermissionClasses()) {\n const p = new P()\n if (!(await p.hasPermission(req, this))) {\n if (!user.isAuthenticated) throw new NotAuthenticated()\n throw new PermissionDenied((p.message as any) ?? null, p.code ?? null)\n }\n }\n }\n\n /** AI SDK tool set for a run: validation, `onToolCall`, context and error normalization included. */\n buildToolSet(ctx: AgentRunContext, tools: AgentTool[] = this.getTools()): ToolSet {\n const ghuri = tryGetContext()\n const set: ToolSet = {}\n for (const t of tools) {\n set[t.name] = aiTool({\n description: t.description,\n inputSchema: jsonSchema(t.inputSchema as JSONSchema7, {\n validate: (value: unknown) => {\n try {\n return { success: true, value: t.parse ? t.parse(value) : value }\n } catch (error) {\n return { success: false, error: toToolError(error, t.name) }\n }\n },\n }),\n execute: (input: unknown, opts: { toolCallId: string; abortSignal?: AbortSignal }) =>\n inContext(ghuri, async () => {\n const toolCtx: ToolContext = {\n user: ctx.user,\n agent: this,\n conversationId: ctx.conversationId,\n toolCallId: opts.toolCallId,\n signal: opts.abortSignal ?? ctx.signal,\n request: ctx.request,\n }\n try {\n await this.onToolCall?.({ toolName: t.name, toolCallId: opts.toolCallId, input }, ctx)\n return await t.execute(input, toolCtx)\n } catch (err) {\n throw toToolError(err, t.name)\n }\n }),\n } as any)\n }\n return set\n }\n\n protected async prepare(input: AgentInput, opts: RunOptions): Promise<Prepared> {\n const user = opts.user ?? anonymousUser\n if (opts.checkPermissions) await this.checkPermissions(user, opts.request)\n // Resolve the model first: a missing provider / key / binding must not leave an empty conversation behind.\n const model = await resolveModel(this.model)\n const agentName = this.getName()\n const useMemory = opts.memory ?? (this.memory !== false && memoryAvailable())\n let conversation: Conversation | undefined\n let history: ModelMessage[] = []\n if (opts.conversationId) {\n if (!memoryAvailable()) {\n throw new ImproperlyConfigured(\n 'conversationId requires the agents app: add AgentsConfig to INSTALLED_APPS.',\n )\n }\n conversation = await getConversation(agentName, opts.conversationId, user)\n history = await loadMessages(conversation)\n } else if (useMemory) {\n conversation = await createConversation(agentName, user, { title: opts.title ?? titleFrom(input) })\n }\n const newMessages: ModelMessage[] =\n typeof input === 'string' ? [{ role: 'user', content: input }] : [...input]\n const ctx: AgentRunContext = {\n agent: this,\n agentName,\n user,\n input,\n conversation,\n conversationId: conversation ? String(conversation.pk) : undefined,\n messages: [...history, ...newMessages],\n newMessages,\n signal: opts.signal,\n request: opts.request,\n extra: opts.context ?? {},\n }\n await this.beforeRun?.(ctx)\n const instructions = await this.getInstructions(ctx)\n return { ctx, model, instructions, tools: this.buildToolSet(ctx), ghuri: tryGetContext() }\n }\n\n protected callSettings(p: Prepared): Record<string, unknown> {\n return {\n model: p.model,\n ...(p.instructions ? { instructions: p.instructions } : {}),\n messages: p.ctx.messages,\n tools: p.tools,\n stopWhen: stepCountIs(this.maxSteps ?? agentsSettings().MAX_STEPS ?? DEFAULT_MAX_STEPS),\n ...(this.temperature !== undefined ? { temperature: this.temperature } : {}),\n ...(this.maxOutputTokens !== undefined ? { maxOutputTokens: this.maxOutputTokens } : {}),\n ...(this.providerOptions ? { providerOptions: this.providerOptions } : {}),\n ...(p.ctx.signal ? { abortSignal: p.ctx.signal } : {}),\n }\n }\n\n protected async finish(\n p: Prepared,\n r: {\n text: string\n responseMessages: ModelMessage[]\n content: ReadonlyArray<any>\n usage: LanguageModelUsage\n finishReason: string\n steps: number\n },\n ): Promise<AgentRunResult> {\n const messages = [...p.ctx.newMessages, ...r.responseMessages]\n if (p.ctx.conversation) await saveMessages(p.ctx.conversation, messages)\n const result: AgentRunResult = {\n text: r.text,\n messages,\n toolCalls: toolCallsFrom(r.content),\n usage: r.usage,\n finishReason: r.finishReason,\n steps: r.steps,\n conversationId: p.ctx.conversationId,\n }\n await this.afterRun?.(result, p.ctx)\n return result\n }\n\n /**\n * Run the agent to completion (tool loop included). Tool failures (permission denied, validation, not\n * found) are returned to the model as tool errors; the run itself only throws for model / config errors.\n */\n async run(input: AgentInput, opts: RunOptions = {}): Promise<AgentRunResult> {\n const p = await this.prepare(input, opts)\n const res = await generateText(this.callSettings(p) as any)\n return this.finish(p, {\n text: res.text,\n responseMessages: res.responseMessages as ModelMessage[],\n content: res.content,\n usage: res.usage,\n finishReason: res.finishReason,\n steps: res.steps.length,\n })\n }\n\n /**\n * Run in the background through a Cloudflare Queue (`AGENTS.QUEUE_BINDING`); a consumer registered with\n * `AgentRouter.consumeQueue()` performs the run. Returns the conversation id to poll.\n */\n async enqueue(input: AgentInput, opts: EnqueueOptions = {}): Promise<{ conversationId?: string }> {\n return enqueueRun(this, input, opts)\n }\n\n /**\n * Stream a run. Use `toUIMessageStreamResponse()` for AI SDK UI (`useChat`) / SSE clients, or `textStream`.\n * The conversation is saved when the stream finishes; `await stream.done` for the final result.\n */\n async stream(input: AgentInput, opts: RunOptions = {}): Promise<AgentStream> {\n const p = await this.prepare(input, opts)\n const result = streamText(this.callSettings(p) as any) as StreamTextResult<ToolSet, any, any>\n const done = (async () => {\n const [text, responseMessages, content, usage, finishReason, steps] = await Promise.all([\n result.text,\n result.responseMessages,\n result.content,\n result.usage,\n result.finishReason,\n result.steps,\n ])\n return inContext(p.ghuri, () =>\n this.finish(p, {\n text,\n responseMessages: responseMessages as ModelMessage[],\n content,\n usage,\n finishReason,\n steps: steps.length,\n }),\n )\n })()\n done.catch(() => {})\n p.ghuri?.executionCtx?.waitUntil(done.catch(() => {}))\n return new AgentStream(result, done, p.ctx.conversationId)\n }\n}\n\n/** A streaming run (`agent.stream()`). */\nexport class AgentStream {\n constructor(\n /** The AI SDK `streamText` result (fullStream, textStream, …). */\n readonly result: StreamTextResult<ToolSet, any, any>,\n /** Resolves after the stream finished and the conversation was saved. */\n readonly done: Promise<AgentRunResult>,\n readonly conversationId?: string,\n ) {}\n\n /** Plain text deltas. */\n get textStream(): AsyncIterable<string> & ReadableStream<string> {\n return this.result.textStream\n }\n\n /**\n * AI SDK UI message stream chunks (`start`, `text-delta`, `tool-input-available`, `tool-output-available`,\n * `finish`…). The `start` chunk carries `messageMetadata: { conversationId }`. The stream closes only after\n * the conversation was saved.\n */\n toUIMessageStream(): ReadableStream<UIMessageChunk> {\n const conversationId = this.conversationId\n const done = this.done\n const stream = this.result.toUIMessageStream({\n messageMetadata: ({ part }: { part: { type: string } }) =>\n part.type === 'start' && conversationId ? { conversationId } : undefined,\n onError: (error: unknown) => errorText(error),\n } as any) as unknown as ReadableStream<UIMessageChunk>\n return stream.pipeThrough(\n new TransformStream<UIMessageChunk, UIMessageChunk>({\n async flush(controller) {\n try {\n await done\n } catch (err) {\n controller.enqueue({ type: 'error', errorText: errorText(err) } as UIMessageChunk)\n }\n },\n }),\n )\n }\n\n /** An SSE `Response` in the AI SDK UI message stream protocol (header `x-conversation-id`). */\n toUIMessageStreamResponse(init: { status?: number; headers?: Record<string, string> } = {}): Response {\n return createUIMessageStreamResponse({\n status: init.status,\n headers: {\n ...(this.conversationId ? { 'x-conversation-id': this.conversationId } : {}),\n ...(init.headers ?? {}),\n },\n stream: this.toUIMessageStream(),\n })\n }\n}\n\nexport { ConversationNotFound }\n","import { apps, type RequestUser } from '@ghuri/core'\nimport type { ModelMessage } from 'ai'\nimport { ToolError } from './errors'\nimport { Conversation, Message } from './models'\n\n/** The conversation does not exist, belongs to another agent, or is not owned by the user. */\nexport class ConversationNotFound extends ToolError {\n constructor(message: string) {\n super(message, { status: 404 })\n }\n}\n\n/** Is conversation memory available (the `agents` app installed)? */\nexport function memoryAvailable(): boolean {\n try {\n return apps.ready && apps.isInstalled('agents')\n } catch {\n return false\n }\n}\n\n/** `user.pk` for authenticated users, otherwise null (anonymous conversations have no owner). */\nexport function ownerPk(user: RequestUser | null | undefined): unknown {\n return user?.isAuthenticated ? user.pk : null\n}\n\n/** Is `user` the owner of `conversation`? (Anonymous conversations are owned by anonymous users.) */\nexport function isOwner(conversation: Conversation, user: RequestUser | null | undefined): boolean {\n const owner = conversation.userId ?? null\n const pk = ownerPk(user)\n if (owner === null || pk === null) return owner === null && pk === null\n return String(owner) === String(pk)\n}\n\n/** A user's conversation with `agent`, or `ConversationNotFound`. */\nexport async function getConversation(\n agent: string,\n id: string,\n user: RequestUser | null | undefined,\n): Promise<Conversation> {\n let conv: Conversation | null = null\n try {\n conv = await Conversation.objects.filter({ id: String(id), agent }).first()\n } catch {\n conv = null\n }\n if (!conv || !isOwner(conv, user)) throw new ConversationNotFound(`Conversation '${id}' not found.`)\n return conv\n}\n\n/** Start a conversation owned by `user`. */\nexport async function createConversation(\n agent: string,\n user: RequestUser | null | undefined,\n opts: { title?: string; metadata?: Record<string, unknown> } = {},\n): Promise<Conversation> {\n const pk = ownerPk(user)\n return Conversation.objects.create({\n agent,\n title: (opts.title ?? '').slice(0, 200),\n metadata: opts.metadata ?? {},\n ...(pk !== null ? { userId: pk } : {}),\n } as any)\n}\n\n/** The stored messages of a conversation, as AI SDK model messages (oldest first). */\nexport async function loadMessages(conversation: Conversation | string): Promise<ModelMessage[]> {\n const id = typeof conversation === 'string' ? conversation : String(conversation.pk)\n const rows = await Message.objects.filter({ conversation: id }).orderBy('id')\n return rows.map((r: any) => ({ role: r.role, content: r.content }) as ModelMessage)\n}\n\n/** JSON-safe copy of a message's content (binary file data is base64-encoded). */\nfunction jsonContent(content: unknown): unknown {\n return JSON.parse(\n JSON.stringify(content, (_k, v) => {\n if (v instanceof Uint8Array) {\n let s = ''\n for (const b of v) s += String.fromCharCode(b)\n return btoa(s)\n }\n if (v instanceof URL) return v.toString()\n return v\n }),\n )\n}\n\n/** Append messages to a conversation and touch its `updatedAt`. */\nexport async function saveMessages(conversation: Conversation, messages: ModelMessage[]): Promise<void> {\n if (!messages.length) return\n await Message.objects.bulkCreate(\n messages.map(\n (m) =>\n new Message({\n conversationId: String(conversation.pk),\n role: m.role,\n content: jsonContent(m.content),\n } as any),\n ),\n )\n await conversation.save({ updateFields: ['updatedAt'] })\n}\n\n/** A short title from the first user message. */\nexport function titleFrom(input: string | ModelMessage[]): string {\n let text = ''\n if (typeof input === 'string') text = input\n else {\n const first = input.find((m) => m.role === 'user')\n const c = first?.content\n if (typeof c === 'string') text = c\n else if (Array.isArray(c)) text = c.map((p: any) => (p.type === 'text' ? p.text : '')).join(' ')\n }\n text = text.replace(/\\s+/g, ' ').trim()\n return text.length > 80 ? `${text.slice(0, 77)}...` : text\n}\n","import { GhuriError } from '@ghuri/core'\n\n/** Base class of `@ghuri/agents` errors. */\nexport class AgentError extends GhuriError {}\n\n/**\n * A tool failed in a way the model should see (permission denied, validation error, not found…). Thrown from a\n * tool's `execute`, it becomes a tool error for the model (the run continues) and `isError: true` over MCP.\n */\nexport class ToolError extends AgentError {\n /** HTTP-like status (403, 400, 404…) when the error came from a view. */\n status?: number\n /** Structured details (DRF error body, validation errors…). */\n detail?: unknown\n\n constructor(message: string, opts: { status?: number; detail?: unknown; cause?: unknown } = {}) {\n super(message, { cause: opts.cause })\n this.status = opts.status\n this.detail = opts.detail\n }\n\n toJSON(): Record<string, unknown> {\n return {\n error: this.message,\n ...(this.status !== undefined ? { status: this.status } : {}),\n ...(this.detail !== undefined ? { detail: this.detail } : {}),\n }\n }\n}\n\n/** Tool input did not match the tool's schema. */\nexport class ToolInputError extends ToolError {\n constructor(message: string, detail?: unknown) {\n super(message, { status: 400, detail })\n }\n}\n\n/** A tool name that no agent / MCP server exposes. */\nexport class UnknownToolError extends AgentError {}\n\n/** A `'provider:model'` string could not be resolved. */\nexport class ModelResolutionError extends AgentError {}\n","import { apps, tryGetContext } from '@ghuri/core'\nimport {\n CASCADE,\n CharField,\n DateTimeField,\n ForeignKey,\n JSONField,\n type Manager,\n Model,\n type ModelClass,\n UUIDField,\n} from '@ghuri/orm'\n\n/** The (swappable) user model: `AUTH_USER_MODEL`, default `auth.User`. Resolved lazily. */\nfunction userModel(): ModelClass {\n const label = (tryGetContext()?.settings.AUTH_USER_MODEL as string | undefined) ?? 'auth.User'\n return apps.getModel(label) as ModelClass\n}\n\nfunction newConversationId(): string {\n return crypto.randomUUID()\n}\n\nfunction emptyMetadata(): Record<string, unknown> {\n return {}\n}\n\n/** A chat thread between a user and one agent (table `agents_conversation`). */\nexport class Conversation extends Model({\n id: new UUIDField({ primaryKey: true, default: newConversationId, editable: false }),\n user: new ForeignKey(userModel, {\n null: true,\n blank: true,\n onDelete: CASCADE,\n relatedName: 'agentConversations',\n }),\n agent: new CharField({ maxLength: 100, dbIndex: true }),\n title: new CharField({ maxLength: 200, blank: true, default: '' }),\n metadata: new JSONField({ default: emptyMetadata, blank: true }),\n createdAt: new DateTimeField({ autoNowAdd: true }),\n updatedAt: new DateTimeField({ autoNow: true }),\n}) {\n declare static objects: Manager<Conversation>\n static Meta = { appLabel: 'agents', ordering: ['-updatedAt'], verboseName: 'conversation' }\n\n toString(): string {\n return this.title || String(this.id)\n }\n}\n\n/** Roles stored in `Message.role` (AI SDK model message roles). */\nexport const MESSAGE_ROLES = ['system', 'user', 'assistant', 'tool'] as const\nexport type MessageRole = (typeof MESSAGE_ROLES)[number]\n\n/**\n * One AI SDK model message of a conversation (table `agents_message`). `content` is the message content as\n * JSON: a string, or parts (text, tool calls with their inputs, tool results / errors).\n */\nexport class Message extends Model({\n conversation: new ForeignKey(() => Conversation, { onDelete: CASCADE, relatedName: 'messages' }),\n role: new CharField({ maxLength: 20, choices: MESSAGE_ROLES.map((r) => [r, r] as [string, string]) }),\n content: new JSONField({ null: true }),\n createdAt: new DateTimeField({ autoNowAdd: true }),\n}) {\n declare static objects: Manager<Message>\n declare conversationId: string\n static Meta = { appLabel: 'agents', ordering: ['id'], verboseName: 'message' }\n}\n","import { type Env, tryGetContext } from '@ghuri/core'\nimport type { LanguageModel } from 'ai'\nimport { ModelResolutionError } from './errors'\nimport { type AgentsSettings, agentsSettings, type ProviderConfig } from './settings'\n\nexport interface ProviderContext {\n /** Worker bindings / environment variables of the current request. */\n env: Env\n settings: AgentsSettings\n /** `AGENTS.PROVIDERS[name]` (empty object when unset). */\n config: ProviderConfig\n}\n\n/** Builds a model for `'<provider>:<modelId>'`. Import provider packages lazily inside the factory. */\nexport type ProviderFactory = (\n modelId: string,\n ctx: ProviderContext,\n) => LanguageModel | Promise<LanguageModel>\n\nconst KEY = Symbol.for('ghuri.agents.providers')\nconst g = globalThis as any\nif (!g[KEY]) g[KEY] = new Map<string, ProviderFactory>()\nconst providers: Map<string, ProviderFactory> = g[KEY]\n\n/**\n * Register (or replace) a model provider used by `'name:model-id'` strings.\n *\n * ```ts\n * registerProvider('google', async (id, { config }) => {\n * const { createGoogleGenerativeAI } = await import('@ai-sdk/google')\n * return createGoogleGenerativeAI({ apiKey: config.apiKey })(id)\n * })\n * ```\n */\nexport function registerProvider(name: string, factory: ProviderFactory): void {\n providers.set(name, factory)\n}\n\nexport function unregisterProvider(name: string): boolean {\n return providers.delete(name)\n}\n\n/** Names of registered providers. */\nexport function getProviders(): string[] {\n return [...providers.keys()]\n}\n\nfunction processEnv(name: string): string | undefined {\n const p = (globalThis as any).process\n return p?.env?.[name]\n}\n\nfunction apiKey(ctx: ProviderContext, envName: string): string | undefined {\n const v = ctx.config.apiKey ?? ctx.env?.[envName] ?? processEnv(envName)\n return typeof v === 'string' && v ? v : undefined\n}\n\nfunction missingPackage(pkg: string, provider: string, cause: unknown): ModelResolutionError {\n return new ModelResolutionError(\n `The '${provider}:' model provider needs the '${pkg}' package: npm install ${pkg}`,\n { cause } as never,\n )\n}\n\nfunction withoutKnown(config: ProviderConfig): Record<string, unknown> {\n const { apiKey: _k, ...rest } = config\n return rest\n}\n\n// Each import sits in its own try block: bundlers (esbuild / wrangler) then leave a missing optional\n// provider package unresolved instead of failing the build, and only used providers are ever loaded.\n\nregisterProvider('workers-ai', async (modelId, ctx) => {\n const bindingName = ctx.settings.AI_BINDING ?? 'AI'\n const binding = ctx.env?.[bindingName]\n if (!binding) {\n throw new ModelResolutionError(\n `Workers AI binding '${bindingName}' not found in env. Add \"ai\": { \"binding\": \"${bindingName}\" } to wrangler.jsonc or set AGENTS.AI_BINDING.`,\n )\n }\n let mod: typeof import('workers-ai-provider')\n try {\n mod = await import('workers-ai-provider')\n } catch (err) {\n throw missingPackage('workers-ai-provider', 'workers-ai', err)\n }\n return mod.createWorkersAI({ ...(withoutKnown(ctx.config) as object), binding } as any)(modelId as any)\n})\n\nregisterProvider('anthropic', async (modelId, ctx) => {\n let mod: typeof import('@ai-sdk/anthropic')\n try {\n mod = await import('@ai-sdk/anthropic')\n } catch (err) {\n throw missingPackage('@ai-sdk/anthropic', 'anthropic', err)\n }\n return mod.createAnthropic({ ...withoutKnown(ctx.config), apiKey: apiKey(ctx, 'ANTHROPIC_API_KEY') })(\n modelId,\n )\n})\n\nregisterProvider('openai', async (modelId, ctx) => {\n let mod: typeof import('@ai-sdk/openai')\n try {\n mod = await import('@ai-sdk/openai')\n } catch (err) {\n throw missingPackage('@ai-sdk/openai', 'openai', err)\n }\n return mod.createOpenAI({ ...withoutKnown(ctx.config), apiKey: apiKey(ctx, 'OPENAI_API_KEY') })(modelId)\n})\n\n/** Is `value` an AI SDK language model instance (not a string id)? */\nexport function isLanguageModel(value: unknown): boolean {\n return (\n !!value &&\n typeof value === 'object' &&\n typeof (value as any).modelId === 'string' &&\n (typeof (value as any).doGenerate === 'function' || typeof (value as any).doStream === 'function')\n )\n}\n\n/**\n * Resolve an agent's `model`: an AI SDK `LanguageModel` is returned as is; `'provider:model-id'` strings go\n * through the provider registry (`workers-ai:`, `anthropic:`, `openai:` built in). Falls back to\n * `AGENTS.DEFAULT_MODEL`.\n */\nexport async function resolveModel(model?: string | LanguageModel | null, env?: Env): Promise<LanguageModel> {\n const settings = agentsSettings()\n const m = model ?? settings.DEFAULT_MODEL\n if (!m) {\n throw new ModelResolutionError(\n \"No model configured: set `model` on the agent (e.g. 'workers-ai:@cf/meta/llama-3.3-70b-instruct-fp8-fast') or AGENTS.DEFAULT_MODEL.\",\n )\n }\n if (typeof m !== 'string') return m\n const i = m.indexOf(':')\n if (i <= 0) {\n throw new ModelResolutionError(\n `Model '${m}' must be '<provider>:<model-id>' (providers: ${getProviders().join(', ')}).`,\n )\n }\n const name = m.slice(0, i)\n const modelId = m.slice(i + 1)\n const factory = providers.get(name)\n if (!factory) {\n throw new ModelResolutionError(\n `Unknown model provider '${name}' in '${m}' (registered: ${getProviders().join(', ')}). Use registerProvider().`,\n )\n }\n return factory(modelId, {\n env: env ?? tryGetContext()?.env ?? {},\n settings,\n config: settings.PROVIDERS?.[name] ?? {},\n })\n}\n","import { tryGetContext } from '@ghuri/core'\nimport type { AuthenticationClass, PermissionClass } from '@ghuri/rest'\nimport { IsAuthenticated } from '@ghuri/rest'\nimport type { LanguageModel } from 'ai'\n\n/** Credentials / options for one provider (`AGENTS.PROVIDERS.anthropic`). */\nexport interface ProviderConfig {\n apiKey?: string\n baseURL?: string\n /** Extra options passed to the provider factory (`createAnthropic({...})`). */\n [option: string]: unknown\n}\n\n/** `AGENTS` settings. Every key is optional. */\nexport interface AgentsSettings {\n /** Model used by agents without a `model` (`'workers-ai:@cf/meta/llama-3.3-70b-instruct-fp8-fast'`). */\n DEFAULT_MODEL?: string | LanguageModel\n /** Workers AI binding name (default `'AI'`). */\n AI_BINDING?: string\n /** Provider credentials: `{ anthropic: { apiKey }, openai: { apiKey }, 'workers-ai': { gateway } }`. */\n PROVIDERS?: Record<string, ProviderConfig>\n /** Default step limit of the tool loop (default 10). */\n MAX_STEPS?: number\n /** Authentication for the chat / MCP endpoints (default `REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES`). */\n AUTHENTICATION_CLASSES?: AuthenticationClass[]\n /** Permission classes for agents that don't set `permissionClasses` (default `[IsAuthenticated]`). */\n PERMISSION_CLASSES?: PermissionClass[]\n /** Queue producer binding used by `agent.enqueue()` (default `'AGENTS_QUEUE'`). */\n QUEUE_BINDING?: string\n}\n\ndeclare module '@ghuri/core' {\n interface GhuriSettings {\n /** `@ghuri/agents` settings. */\n AGENTS?: AgentsSettings\n }\n}\n\nexport const DEFAULT_MAX_STEPS = 10\n\n/** The `AGENTS` settings of the current context (empty outside a context). */\nexport function agentsSettings(): AgentsSettings {\n const s = tryGetContext()?.settings.AGENTS\n return (s && typeof s === 'object' ? s : {}) as AgentsSettings\n}\n\n/** Default permission classes for agent endpoints. */\nexport function defaultPermissionClasses(): PermissionClass[] {\n return agentsSettings().PERMISSION_CLASSES ?? [IsAuthenticated]\n}\n","import {\n anonymousUser,\n apps,\n ImproperlyConfigured,\n type MessageBatchLike,\n onQueue,\n type RequestUser,\n tryGetContext,\n} from '@ghuri/core'\nimport type { Agent, AgentInput } from './agent'\nimport { createConversation, memoryAvailable, ownerPk, titleFrom } from './memory'\nimport { agentsSettings } from './settings'\n\n/** Message body sent to the queue by `enqueue()`. */\nexport interface AgentJob {\n type: 'ghuri.agents.run'\n agent: string\n input: AgentInput\n /** Primary key of the user to run as (null: anonymous). */\n userId: unknown\n conversationId?: string\n context?: Record<string, unknown>\n}\n\nexport const AGENT_JOB_TYPE = 'ghuri.agents.run'\n\nexport interface EnqueueOptions {\n user?: RequestUser | null\n conversationId?: string | null\n /** Queue producer binding (default `AGENTS.QUEUE_BINDING`, else `'AGENTS_QUEUE'`). */\n binding?: string\n context?: Record<string, unknown>\n}\n\n/**\n * Send a run to a Cloudflare Queue (consumed by `AgentRouter.consumeQueue()`). A conversation is created up\n * front (when memory is available) so callers can poll it.\n */\nexport async function enqueueRun(\n agent: Agent,\n input: AgentInput,\n opts: EnqueueOptions = {},\n): Promise<{ conversationId?: string }> {\n const name = opts.binding ?? agentsSettings().QUEUE_BINDING ?? 'AGENTS_QUEUE'\n const queue = tryGetContext()?.env?.[name]\n if (!queue || typeof queue.send !== 'function') {\n throw new ImproperlyConfigured(\n `Queue producer binding '${name}' not found: add it to wrangler.jsonc (\"queues\": { \"producers\": [...] }) or set AGENTS.QUEUE_BINDING.`,\n )\n }\n let conversationId = opts.conversationId ?? undefined\n if (!conversationId && agent.memory !== false && memoryAvailable()) {\n const conv = await createConversation(agent.getName(), opts.user, { title: titleFrom(input) })\n conversationId = String(conv.pk)\n }\n const job: AgentJob = {\n type: AGENT_JOB_TYPE,\n agent: agent.getName(),\n input,\n userId: ownerPk(opts.user),\n ...(conversationId ? { conversationId } : {}),\n ...(opts.context ? { context: opts.context } : {}),\n }\n await queue.send(job)\n return { conversationId }\n}\n\n/** Load the user a queued run acts for (`AUTH_USER_MODEL`); anonymous when `userId` is null. */\nexport async function loadJobUser(userId: unknown): Promise<RequestUser> {\n if (userId === null || userId === undefined) return anonymousUser\n const label = (tryGetContext()?.settings.AUTH_USER_MODEL as string | undefined) ?? 'auth.User'\n const model = apps.getModel(label) as any\n return model.objects.get({ pk: userId })\n}\n\n/**\n * Register a queue consumer running queued agent jobs with `create(name)` (an `AgentRouter`'s factory).\n * Messages that are not agent jobs are left alone; failed runs are retried.\n */\nexport function consumeAgentQueue(queue: string, create: (name: string) => Agent): () => void {\n return onQueue(queue, async (batch: MessageBatchLike<any>) => {\n for (const msg of batch.messages) {\n const job = msg.body as AgentJob\n if (!job || job.type !== AGENT_JOB_TYPE) continue\n try {\n const agent = create(job.agent)\n const user = await loadJobUser(job.userId)\n await agent.run(job.input, {\n user,\n conversationId: job.conversationId ?? null,\n context: job.context,\n })\n msg.ack()\n } catch (err) {\n console.error(`[ghuri.agents] queued run of '${job.agent}' failed:`, err)\n msg.retry()\n }\n }\n })\n}\n","import { type GhuriContext, HttpError, runWithContext, tryGetContext, ValidationError } from '@ghuri/core'\nimport { APIException } from '@ghuri/rest'\nimport { ToolError } from '../errors'\nimport type { AgentTool, ToolContext } from './types'\n\n/** Run `fn` inside `ctx` (tools may run from stream callbacks outside the request's async context). */\nexport function inContext<T>(ctx: GhuriContext | undefined, fn: () => T): T {\n if (!ctx || tryGetContext() === ctx) return fn()\n return runWithContext(ctx, fn)\n}\n\nfunction isDebug(): boolean {\n return !!tryGetContext()?.settings.DEBUG\n}\n\n/**\n * Normalize anything thrown by a tool into a `ToolError` the model / MCP client may see. Expected failures\n * (permission denied, not found, validation) keep their message; unexpected errors are reported generically\n * unless `DEBUG` is on (the real error is logged).\n */\nexport function toToolError(err: unknown, toolName?: string): ToolError {\n if (err instanceof ToolError) return err\n if (err instanceof APIException) {\n return new ToolError(`${err.message || 'Request failed.'} (HTTP ${err.statusCode})`, {\n status: err.statusCode,\n cause: err,\n })\n }\n if (err instanceof HttpError) {\n return new ToolError(`${err.message} (HTTP ${(err as any).status})`, {\n status: (err as any).status,\n cause: err,\n })\n }\n if (err instanceof ValidationError) {\n const detail = (err as any).messageDict ?? (err as any).messages\n return new ToolError(`Validation failed: ${JSON.stringify(detail ?? err.message)}`, {\n status: 400,\n detail,\n cause: err,\n })\n }\n if (err instanceof Error && err.name === 'AbortError') return new ToolError('Aborted.', { cause: err })\n console.error(`[ghuri.agents] tool ${toolName ?? ''} failed:`, err)\n const message = isDebug() && err instanceof Error ? err.message : 'The tool failed with an internal error.'\n return new ToolError(message, { status: 500, cause: err })\n}\n\n/** Validate arguments and run a tool, normalizing errors (used by agents and the MCP server). */\nexport async function runTool(tool: AgentTool, args: unknown, ctx: ToolContext): Promise<unknown> {\n try {\n const input = tool.parse ? tool.parse(args) : (args ?? {})\n return await tool.execute(input, ctx)\n } catch (err) {\n throw toToolError(err, tool.name)\n }\n}\n","import { ImproperlyConfigured } from '@ghuri/core'\nimport type { z } from 'zod'\nimport { makeParser, sanitizeToolName, toJSONSchema } from './schema'\nimport type { AgentTool, JSONSchema, ToolAnnotations, ToolContext } from './types'\n\n/** Marker on methods decorated with `@tool`. */\nexport const TOOL: unique symbol = Symbol.for('ghuri.agents.tool') as any\n/** Options carried by the decorator returned from `tool()` (for `static tools = {...}` and standalone tools). */\nexport const TOOL_OPTIONS: unique symbol = Symbol.for('ghuri.agents.toolOptions') as any\n\ntype InputOf<S> = S extends z.ZodType ? z.output<S> : Record<string, any>\n\nexport interface ToolOptions<S = z.ZodType | JSONSchema | undefined> {\n /** Tool name (default: the method / key name). Sanitized to `[A-Za-z0-9_-]{1,64}`. */\n name?: string\n /** What the tool does — the model reads this to decide when to call it. */\n description: string\n /** Arguments: a Zod object schema (validated) or a JSON Schema object. Omit for no arguments. */\n input?: S\n /** JSON Schema of the result (advertised over MCP as `outputSchema`). */\n output?: JSONSchema\n annotations?: ToolAnnotations\n /** Standalone tools: the implementation (methods decorated with `@tool` don't need it). */\n execute?: (input: InputOf<S>, ctx: ToolContext) => unknown\n}\n\n/** A `tool()` result: a TC39 / legacy method decorator that also carries its options. */\nexport interface ToolDecorator<S = any> {\n (value: any, context?: any, descriptor?: PropertyDescriptor): any\n readonly [TOOL_OPTIONS]: ToolOptions<S>\n}\n\nfunction mark(fn: any, name: string, opts: ToolOptions): void {\n if (typeof fn !== 'function') throw new TypeError('@tool() can only decorate methods.')\n fn[TOOL] = { ...opts, name: opts.name ?? name }\n}\n\n/**\n * Legacy (`experimentalDecorators`) method decorators compiled by Babel with decorator metadata — e.g. jiti, the\n * TypeScript loader of the `ghuri` CLI — may receive the class prototype instead of the property descriptor\n * (the no-op metadata decorators return their target). Recover the real descriptor in that case.\n */\nfunction legacyMethodDescriptor(\n target: unknown,\n key: unknown,\n descriptor: unknown,\n): PropertyDescriptor | undefined {\n if (typeof key !== 'string' && typeof key !== 'symbol') return undefined\n if (!target || (typeof target !== 'object' && typeof target !== 'function')) return undefined\n if (descriptor !== undefined && descriptor !== target) return undefined\n const real = Object.getOwnPropertyDescriptor(target, key)\n return real && typeof real.value === 'function' ? real : undefined\n}\n\n/**\n * Declare a tool. Three forms:\n *\n * ```ts\n * class SupportAgent extends Agent {\n * // 1. decorator (standard TC39 decorators)\n * @tool({ description: 'Refund an order', input: z.object({ orderId: z.number() }) })\n * async refund({ orderId }, ctx) { ... }\n *\n * // 2. without decorators: options in a static map, implementation in the method of the same name\n * static tools = { refund: tool({ description: 'Refund an order', input: z.object({ orderId: z.number() }) }) }\n *\n * // 3. standalone, with `execute`\n * tools = [tool({ name: 'now', description: 'Current time', execute: () => new Date().toISOString() })]\n * }\n * ```\n */\nexport function tool<S extends z.ZodType | JSONSchema | undefined = undefined>(\n opts: ToolOptions<S>,\n): ToolDecorator<S> {\n if (!opts || typeof opts.description !== 'string')\n throw new TypeError('tool() requires a `description` string.')\n const decorator = ((value: any, context?: any, descriptor?: PropertyDescriptor) => {\n if (descriptor && typeof descriptor.value === 'function') {\n mark(descriptor.value, String(context), opts as ToolOptions)\n return descriptor\n }\n if (typeof value === 'function') {\n const name =\n context && typeof context === 'object' && 'name' in context ? String(context.name) : value.name\n mark(value, name, opts as ToolOptions)\n return value\n }\n const legacy = legacyMethodDescriptor(value, context, descriptor)\n if (legacy) {\n mark(legacy.value, String(context), opts as ToolOptions)\n return legacy\n }\n throw new TypeError('@tool() can only decorate methods.')\n }) as ToolDecorator<S>\n Object.defineProperty(decorator, TOOL_OPTIONS, { value: opts })\n return decorator\n}\n\nexport function isToolDecorator(value: unknown): value is ToolDecorator {\n return typeof value === 'function' && TOOL_OPTIONS in value\n}\n\n/** Build a normalized `AgentTool` from options and an implementation. */\nexport function defineTool(\n name: string,\n opts: ToolOptions<any>,\n execute: (input: any, ctx: ToolContext) => unknown,\n): AgentTool {\n return {\n name: sanitizeToolName(opts.name ?? name),\n description: opts.description,\n inputSchema: toJSONSchema(opts.input),\n ...(opts.output ? { outputSchema: opts.output } : {}),\n ...(opts.annotations ? { annotations: opts.annotations } : {}),\n parse: makeParser(opts.input),\n execute,\n }\n}\n\n/** A standalone `tool({ ..., execute })` → `AgentTool` (`key` names tools declared in a map). */\nexport function standaloneTool(decorator: ToolDecorator, key?: string): AgentTool {\n const opts = decorator[TOOL_OPTIONS]\n if (typeof opts.execute !== 'function') {\n throw new ImproperlyConfigured(\n `tool('${opts.name ?? key ?? opts.description}') has no \\`execute\\`: use it as a method decorator or pass execute.`,\n )\n }\n const name = opts.name ?? key\n if (!name) throw new ImproperlyConfigured(`A standalone tool needs a \\`name\\` (${opts.description}).`)\n return defineTool(name, opts, opts.execute)\n}\n\n/**\n * Tools declared on a class: `@tool` methods and `static tools = { name: tool({...}) }` entries, bound to\n * `instance` (methods receive `(input, ctx)` with `this` = the instance).\n */\nexport function collectDeclaredTools(instance: object): AgentTool[] {\n const cls = instance.constructor as any\n const found = new Map<string, AgentTool>()\n const chain: any[] = []\n for (let p = Object.getPrototypeOf(instance); p && p !== Object.prototype; p = Object.getPrototypeOf(p))\n chain.unshift(p)\n for (const proto of chain) {\n for (const key of Object.getOwnPropertyNames(proto)) {\n if (key === 'constructor') continue\n const fn = Object.getOwnPropertyDescriptor(proto, key)?.value\n if (typeof fn === 'function' && fn[TOOL]) {\n const opts = fn[TOOL] as ToolOptions\n found.set(\n key,\n defineTool(opts.name ?? key, opts, (input, ctx) => (instance as any)[key](input, ctx)),\n )\n }\n }\n }\n const staticChain: any[] = []\n for (let c = cls; c && c !== Function.prototype; c = Object.getPrototypeOf(c)) staticChain.unshift(c)\n for (const c of staticChain) {\n if (!Object.hasOwn(c, 'tools') || !c.tools || typeof c.tools !== 'object' || Array.isArray(c.tools))\n continue\n for (const [key, spec] of Object.entries(c.tools as Record<string, any>)) {\n const opts: ToolOptions | undefined = isToolDecorator(spec)\n ? spec[TOOL_OPTIONS]\n : spec && typeof spec === 'object' && typeof spec.description === 'string'\n ? spec\n : undefined\n if (!opts) continue\n if (typeof opts.execute === 'function') {\n found.set(key, defineTool(opts.name ?? key, opts, opts.execute))\n continue\n }\n if (typeof (instance as any)[key] !== 'function') {\n throw new ImproperlyConfigured(`${c.name}.tools.${key}: the class has no method named '${key}'.`)\n }\n found.set(\n key,\n defineTool(opts.name ?? key, opts, (input, ctx) => (instance as any)[key](input, ctx)),\n )\n }\n }\n return [...found.values()]\n}\n","import { z } from 'zod'\nimport { ToolInputError } from '../errors'\nimport type { JSONSchema } from './types'\n\n/** Make `name` a valid LLM / MCP tool name: `[A-Za-z0-9_-]{1,64}`. */\nexport function sanitizeToolName(name: string): string {\n const s = name\n .replace(/[^A-Za-z0-9_-]+/g, '_')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '')\n return (s || 'tool').slice(0, 64)\n}\n\n/** `partialUpdate` → `partial_update`. */\nexport function snakeCase(s: string): string {\n return s\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[-\\s]+/g, '_')\n .toLowerCase()\n}\n\n/** Is `value` a Zod (v4) schema? */\nexport function isZodSchema(value: unknown): value is z.ZodType {\n return (\n !!value &&\n typeof value === 'object' &&\n '_zod' in (value as object) &&\n typeof (value as z.ZodType).safeParse === 'function'\n )\n}\n\n/** JSON Schema of a tool input given as a Zod schema, a JSON Schema object or nothing (no arguments). */\nexport function toJSONSchema(input: unknown): JSONSchema {\n if (input === undefined || input === null) return { type: 'object', properties: {} }\n if (isZodSchema(input)) {\n const schema = z.toJSONSchema(input, { io: 'input', unrepresentable: 'any' }) as JSONSchema\n delete schema.$schema\n return schema\n }\n if (typeof input === 'object') return { ...(input as JSONSchema) }\n throw new TypeError('Tool input must be a Zod schema or a JSON Schema object.')\n}\n\n/** A parser for tool arguments: Zod schemas validate and coerce; JSON Schemas only require an object. */\nexport function makeParser(input: unknown): (value: unknown) => unknown {\n if (isZodSchema(input)) {\n return (value: unknown) => {\n const res = input.safeParse(value ?? {})\n if (!res.success) {\n const issues = res.error.issues.map((i) => ({ path: i.path.join('.'), message: i.message }))\n const summary = issues.map((i) => (i.path ? `${i.path}: ${i.message}` : i.message)).join('; ')\n throw new ToolInputError(`Invalid arguments: ${summary}`, issues)\n }\n return res.data\n }\n }\n return (value: unknown) => {\n if (value === undefined || value === null) return {}\n if (typeof value !== 'object' || Array.isArray(value))\n throw new ToolInputError('Tool arguments must be a JSON object.')\n return value\n }\n}\n\n/** Remove `readOnly` properties and output-only keywords so a serializer schema is usable as tool input. */\nexport function cleanInputSchema(schema: JSONSchema | undefined): JSONSchema {\n if (!schema) return { type: 'object', properties: {} }\n const { title: _t, ...rest } = schema\n return { ...rest, type: 'object', properties: { ...((schema.properties as object) ?? {}) } }\n}\n\n/** OpenAPI parameter objects (`{ name, schema, description, required }`) → JSON Schema properties. */\nexport function parametersToProperties(params: Array<Record<string, unknown>>): {\n properties: Record<string, JSONSchema>\n required: string[]\n} {\n const properties: Record<string, JSONSchema> = {}\n const required: string[] = []\n for (const p of params) {\n if (p.in && p.in !== 'query') continue\n const name = String(p.name)\n properties[name] = {\n ...((p.schema as JSONSchema) ?? { type: 'string' }),\n ...(p.description ? { description: String(p.description) } : {}),\n }\n if (p.required) required.push(name)\n }\n return { properties, required }\n}\n","import type { RequestUser } from '@ghuri/core'\nimport type { APIRequest } from '@ghuri/rest'\n\n/** A JSON Schema object (draft 2020-12). */\nexport type JSONSchema = Record<string, unknown>\n\n/** Who and what a tool runs for. Every tool executes as `user`. */\nexport interface ToolContext {\n /** The requesting user (tools never escalate beyond this user's permissions). */\n user: RequestUser\n /** The agent running the tool (absent for direct MCP calls). */\n agent?: unknown\n conversationId?: string\n toolCallId?: string\n signal?: AbortSignal\n /** The REST request of the HTTP chat / MCP call, when there is one. */\n request?: APIRequest\n}\n\n/** MCP tool annotations (hints for clients; also useful for UIs). */\nexport interface ToolAnnotations {\n title?: string\n readOnlyHint?: boolean\n destructiveHint?: boolean\n idempotentHint?: boolean\n openWorldHint?: boolean\n}\n\n/**\n * A normalized tool, the common currency of agents (AI SDK tools) and the MCP server. `ModelTools`,\n * `ViewSetTools`, `RouterTools`, `tool()` and `@tool` methods all produce these.\n */\nexport interface AgentTool {\n /** Sanitized name (`posts_list`), unique within an agent / MCP server. */\n name: string\n description: string\n /** JSON Schema of the arguments (always `type: 'object'`). */\n inputSchema: JSONSchema\n /** JSON Schema of the result, when known. */\n outputSchema?: JSONSchema\n annotations?: ToolAnnotations\n /** Validate / coerce raw arguments; throws `ToolInputError`. Defaults to accepting any object. */\n parse?(input: unknown): unknown\n /** Run the tool. Throw `ToolError` for failures the model should see. */\n execute(input: any, ctx: ToolContext): unknown\n}\n\n/** A collection of tools (`ModelTools`, `ViewSetTools`, `RouterTools`, or your own). */\nexport abstract class Toolkit {\n abstract getTools(): AgentTool[]\n}\n\nexport function isToolkit(value: unknown): value is Toolkit {\n return !!value && typeof (value as Toolkit).getTools === 'function'\n}\n\nexport function isAgentTool(value: unknown): value is AgentTool {\n return (\n !!value &&\n typeof value === 'object' &&\n typeof (value as AgentTool).name === 'string' &&\n typeof (value as AgentTool).execute === 'function' &&\n typeof (value as AgentTool).inputSchema === 'object'\n )\n}\n","import { AppConfig, tryGetContext } from '@ghuri/core'\nimport { Migration, migrationsFromModule } from '@ghuri/orm/migrations'\nimport * as agentsMigrations from './migrations/index'\nimport { Conversation, Message } from './models'\n\n/**\n * The agents migrations, adapted to `AUTH_USER_MODEL`: `Conversation.user` points at the custom user model\n * and the migration depends on its app instead of `auth` (Django's `swappable_dependency`).\n */\nfunction migrationsForUserModel(): Record<string, unknown> {\n const label = tryGetContext()?.settings.AUTH_USER_MODEL as string | undefined\n if (!label || label.toLowerCase() === 'auth.user') return agentsMigrations\n const userApp = label.split('.')[0]\n const out: Record<string, Migration> = {}\n for (const [name, m] of migrationsFromModule(agentsMigrations) ?? []) {\n const operations = m.operations.map((op: any) => {\n if (!op.fields) return op\n const fields = Object.fromEntries(\n Object.entries(op.fields as Record<string, any>).map(([k, f]) => {\n const to = f?.options?.to ?? f?.to\n if (typeof to !== 'string' || to.toLowerCase() !== 'auth.user') return [k, f]\n return [k, f.options ? { ...f, options: { ...f.options, to: label } } : { ...f, to: label }]\n }),\n )\n return Object.assign(Object.create(Object.getPrototypeOf(op)), op, { fields })\n })\n const dependencies = m.dependencies.filter((d) => d[0] !== 'auth')\n if (!dependencies.some((d) => d[0] === userApp)) dependencies.push([userApp, '__first__'] as const)\n const adapted = new Migration({ dependencies, operations, initial: m.initial })\n adapted.name = m.name || name\n out[adapted.name] = adapted\n }\n return { migrations: out }\n}\n\n/** `path` when running from the TypeScript sources (makemigrations), undefined in dist / on Workers. */\nfunction appPath(): string | undefined {\n const meta = import.meta as ImportMeta & { dirname?: string; filename?: string }\n if (!meta.dirname || !/[\\\\/]src$/.test(meta.dirname) || !/\\.[cm]?ts$/.test(meta.filename ?? ''))\n return undefined\n return meta.dirname\n}\n\n/**\n * The `agents` app: conversation memory (`Conversation`, `Message`) and its migrations. Add it to\n * `INSTALLED_APPS` (after your user model's app) and run `ghuri migrate` to have agents load and save\n * conversations automatically.\n */\nexport class AgentsConfig extends AppConfig {\n name = '@ghuri/agents'\n override label = 'agents'\n override verboseName = 'Agents'\n override path = appPath()\n override migrations = migrationsForUserModel()\n override models = { Conversation, Message }\n}\n","// Generated by Ghuri makemigrations: every migration of this app, in order. Do not edit.\nimport m0001_initial from './0001_initial'\n\nexport { m0001_initial }\n\n/** Every migration of this app by name, in order. */\nexport const migrations = {\n '0001_initial': m0001_initial,\n}\n","// Generated by Ghuri makemigrations on 2026-11-12 02:50\nimport { Migration, operations as ops } from '@ghuri/orm/migrations'\n\nexport default new Migration({\n initial: true,\n dependencies: [['auth', '0001_initial']],\n operations: [\n ops.CreateModel({\n name: 'Conversation',\n fields: {\n id: {\n type: 'UUIDField',\n primaryKey: true,\n default: { callable: 'newConversationId' },\n editable: false,\n },\n user: {\n type: 'ForeignKey',\n to: 'auth.User',\n onDelete: 'CASCADE',\n null: true,\n blank: true,\n dbIndex: true,\n relatedName: 'agentConversations',\n },\n agent: { type: 'CharField', maxLength: 100, dbIndex: true },\n title: { type: 'CharField', maxLength: 200, blank: true, default: '' },\n metadata: { type: 'JSONField', blank: true, default: { callable: 'emptyMetadata' } },\n createdAt: { type: 'DateTimeField', autoNowAdd: true },\n updatedAt: { type: 'DateTimeField', autoNow: true },\n },\n options: { ordering: ['-updatedAt'], verboseName: 'conversation' },\n }),\n ops.CreateModel({\n name: 'Message',\n fields: {\n id: { type: 'BigAutoField', primaryKey: true },\n conversation: {\n type: 'ForeignKey',\n to: 'agents.Conversation',\n onDelete: 'CASCADE',\n dbIndex: true,\n relatedName: 'messages',\n },\n role: {\n type: 'CharField',\n maxLength: 20,\n choices: [\n ['system', 'system'],\n ['user', 'user'],\n ['assistant', 'assistant'],\n ['tool', 'tool'],\n ],\n },\n content: { type: 'JSONField', null: true },\n createdAt: { type: 'DateTimeField', autoNowAdd: true },\n },\n options: { ordering: ['id'], verboseName: 'message' },\n }),\n ],\n})\n","import { ImproperlyConfigured, path, tryGetContext, type UrlPatterns } from '@ghuri/core'\nimport {\n APIException,\n type APIRequest,\n APIResponse,\n APIView,\n type AuthenticationClass,\n type BaseAuthentication,\n type BasePermission,\n JSONRenderer,\n NotAuthenticated,\n NotFound,\n ValidationError as RestValidationError,\n} from '@ghuri/rest'\nimport type { Agent, AgentInput } from './agent'\nimport { ModelResolutionError } from './errors'\nimport { McpServer, type McpServerOptions } from './mcp'\nimport { ConversationNotFound, getConversation, memoryAvailable } from './memory'\nimport { Conversation, Message } from './models'\nimport { consumeAgentQueue } from './queue'\nimport { agentsSettings } from './settings'\n\nexport type AgentClass = new () => Agent\n\n/**\n * 503: the agent's model can't be used (missing provider package, API key or Workers AI binding). The reason\n * is shown with `DEBUG`; production answers stay generic.\n */\nexport class ModelUnavailable extends APIException {\n static override statusCode = 503\n static override defaultDetail = \"The agent's language model is not available.\"\n static override defaultCode = 'model_unavailable'\n}\n\n/** `AGENTS.AUTHENTICATION_CLASSES`, else `REST_FRAMEWORK.DEFAULT_AUTHENTICATION_CLASSES`. */\nexport function agentAuthenticationClasses(): AuthenticationClass[] | undefined {\n return agentsSettings().AUTHENTICATION_CLASSES\n}\n\n/** Shared base: agent auth settings, permissions from the agent, JSON only (SSE returned as raw responses). */\nabstract class AgentBaseView extends APIView {\n declare agentRouter: AgentRouter\n declare agentName: string\n _agent?: Agent\n\n override rendererClasses = [JSONRenderer]\n\n /** The agent instance serving this request. */\n get agent(): Agent {\n this._agent ??= this.agentRouter.create(this.agentName)\n return this._agent\n }\n\n override getAuthenticators(): BaseAuthentication[] {\n const classes = this.authenticationClasses ?? agentAuthenticationClasses()\n return classes ? classes.map((A) => new A()) : super.getAuthenticators()\n }\n\n override getPermissions(): BasePermission[] {\n if (this.permissionClasses) return super.getPermissions()\n return this.agent.getPermissionClasses().map((P) => new P())\n }\n\n // Never 406: SSE clients send `Accept: text/event-stream`; errors are rendered as JSON.\n override performContentNegotiation(request: APIRequest, _force = false): [any, string] {\n return super.performContentNegotiation(request, true)\n }\n\n protected requireMemory(): void {\n if (!memoryAvailable()) throw new NotFound('Conversation memory is not enabled (install AgentsConfig).')\n }\n}\n\nfunction wantsStream(request: APIRequest): boolean {\n const q = request.queryParams.get('stream')\n if (q !== null) return ['1', 'true', 'yes'].includes(q.toLowerCase())\n return (request.header('accept') ?? '').includes('text/event-stream')\n}\n\n/** Text of the last user message of AI SDK UI messages (`useChat` request bodies). */\nfunction lastUserText(messages: unknown): string | undefined {\n if (!Array.isArray(messages)) return undefined\n for (let i = messages.length - 1; i >= 0; i--) {\n const m = messages[i]\n if (m?.role !== 'user') continue\n if (typeof m.content === 'string') return m.content\n if (Array.isArray(m.parts))\n return m.parts\n .filter((p: any) => p?.type === 'text')\n .map((p: any) => p.text)\n .join('')\n }\n return undefined\n}\n\n/**\n * `POST <name>/chat` — `{ message, conversationId? }` (or an AI SDK `useChat` body with `messages`). Streams the\n * AI SDK UI message stream as SSE when `Accept: text/event-stream` or `?stream=1`, otherwise answers JSON\n * `{ conversationId, text, toolCalls, usage, finishReason }`.\n */\nexport class AgentChatView extends AgentBaseView {\n async post(request: APIRequest): Promise<Response | APIResponse> {\n const body = (request.data ?? {}) as Record<string, any>\n const message = typeof body.message === 'string' ? body.message : lastUserText(body.messages)\n if (typeof message !== 'string' || !message.trim())\n throw new RestValidationError({ message: ['This field is required.'] })\n const conversationId = body.conversationId ?? null\n if (conversationId !== null && typeof conversationId !== 'string')\n throw new RestValidationError({ conversationId: ['Must be a string.'] })\n const input: AgentInput = message\n const opts = { user: request.user, conversationId, request }\n try {\n if (wantsStream(request)) {\n const stream = await this.agent.stream(input, opts)\n return stream.toUIMessageStreamResponse()\n }\n const r = await this.agent.run(input, opts)\n return new APIResponse({\n conversationId: r.conversationId ?? null,\n text: r.text,\n toolCalls: r.toolCalls,\n usage: r.usage,\n finishReason: r.finishReason,\n })\n } catch (err) {\n if (err instanceof ConversationNotFound) throw new NotFound(err.message)\n if (err instanceof ModelResolutionError)\n throw new ModelUnavailable(tryGetContext()?.settings.DEBUG ? err.message : undefined)\n throw err\n }\n }\n}\n\nfunction conversationJSON(c: any): Record<string, unknown> {\n return {\n id: String(c.pk),\n agent: c.agent,\n title: c.title,\n metadata: c.metadata ?? {},\n createdAt: c.createdAt,\n updatedAt: c.updatedAt,\n }\n}\n\n/** `GET <name>/conversations/` — the requesting user's conversations with the agent (newest first). */\nexport class ConversationListView extends AgentBaseView {\n async get(request: APIRequest): Promise<APIResponse> {\n this.requireMemory()\n if (!request.user.isAuthenticated) throw new NotAuthenticated()\n const limit = Math.min(Math.max(Number(request.query.limit) || 50, 1), 200)\n const offset = Math.max(Number(request.query.offset) || 0, 0)\n const qs = Conversation.objects.filter({ agent: this.agentName, user: request.user.pk })\n const [count, rows] = await Promise.all([\n qs.count(),\n qs.orderBy('-updatedAt').slice(offset, offset + limit),\n ])\n return new APIResponse({ count, results: rows.map(conversationJSON) })\n }\n}\n\n/** `GET / DELETE <name>/conversations/<id>/` — one conversation with its messages (owner only). */\nexport class ConversationDetailView extends AgentBaseView {\n protected async conversation(request: APIRequest, id: string): Promise<any> {\n this.requireMemory()\n if (!request.user.isAuthenticated) throw new NotAuthenticated()\n try {\n return await getConversation(this.agentName, id, request.user)\n } catch (err) {\n if (err instanceof ConversationNotFound) throw new NotFound(err.message)\n throw err\n }\n }\n\n async get(request: APIRequest, kwargs: Record<string, any>): Promise<APIResponse> {\n const conv = await this.conversation(request, String(kwargs.id))\n const rows: any[] = await Message.objects.filter({ conversation: String(conv.pk) }).orderBy('id')\n return new APIResponse({\n ...conversationJSON(conv),\n messages: rows.map((m) => ({ id: m.pk, role: m.role, content: m.content, createdAt: m.createdAt })),\n })\n }\n\n async delete(request: APIRequest, kwargs: Record<string, any>): Promise<APIResponse> {\n const conv = await this.conversation(request, String(kwargs.id))\n await conv.delete()\n return new APIResponse(null, { status: 204 })\n }\n}\n\nexport interface AgentRouterOptions {\n /** URL name prefix (default `'agents'`: `agents-support-chat`). */\n urlNamePrefix?: string\n}\n\n/**\n * Serves agents over HTTP (and MCP).\n *\n * ```ts\n * const agents = new AgentRouter()\n * agents.register('support', SupportAgent)\n * export const urlpatterns = [path('agents/', include(agents.urls)), path('mcp/', agents.mcp({ name: 'shop' }))]\n * // POST /agents/support/chat GET /agents/support/conversations/ GET|DELETE /agents/support/conversations/<id>/\n * ```\n */\nexport class AgentRouter {\n readonly registry = new Map<string, AgentClass>()\n readonly opts: AgentRouterOptions\n _urls?: UrlPatterns\n\n constructor(opts: AgentRouterOptions = {}) {\n this.opts = opts\n }\n\n /** Register an agent class under `name` (URL segment, conversation `agent` value, MCP `ask_<name>`). */\n register(name: string, agentClass: AgentClass): this {\n if (!/^[A-Za-z0-9_-]+$/.test(name))\n throw new ImproperlyConfigured(`Agent name '${name}' may only contain letters, digits, '_' and '-'.`)\n if (this.registry.has(name))\n throw new ImproperlyConfigured(`An agent named '${name}' is already registered.`)\n this.registry.set(name, agentClass)\n this._urls = undefined\n return this\n }\n\n /**\n * Consume queued runs (`agent.enqueue()`) from the Cloudflare Queue named `queue` (default: every queue).\n * Call it once, e.g. from an AppConfig's `ready()`. Returns an unregister function.\n */\n consumeQueue(queue = '*'): () => void {\n return consumeAgentQueue(queue, (name) => this.create(name))\n }\n\n /** A fresh agent instance for `name`. */\n create(name: string): Agent {\n const cls = this.registry.get(name)\n if (!cls) throw new ImproperlyConfigured(`No agent registered as '${name}'.`)\n const agent = new cls()\n agent.agentName = name\n return agent\n }\n\n /** Registered agent names. */\n get names(): string[] {\n return [...this.registry.keys()]\n }\n\n getUrls(): UrlPatterns {\n const prefix = this.opts.urlNamePrefix ?? 'agents'\n const out: UrlPatterns = []\n for (const name of this.registry.keys()) {\n const init = { agentRouter: this, agentName: name }\n const chat = AgentChatView.asView(init)\n out.push(\n path(`${name}/chat/`, chat, { name: `${prefix}-${name}-chat` }),\n path(`${name}/chat`, chat),\n path(`${name}/conversations/`, ConversationListView.asView(init), {\n name: `${prefix}-${name}-conversations`,\n }),\n path(`${name}/conversations/<uuid:id>/`, ConversationDetailView.asView(init), {\n name: `${prefix}-${name}-conversation`,\n }),\n )\n }\n return out\n }\n\n /**\n * A Streamable HTTP MCP endpoint exposing `tools` plus the registered agents as `ask_<name>` tools\n * (`agents: false` to leave them out, or a list of names). Mount it with `path('mcp/', agents.mcp())`.\n */\n mcp(opts: Omit<McpServerOptions, 'agents'> & { agents?: boolean | string[] } = {}): UrlPatterns {\n return this.mcpServer(opts).urls\n }\n\n /** The `McpServer` behind `mcp()` (for tests / custom mounting). */\n mcpServer(opts: Omit<McpServerOptions, 'agents'> & { agents?: boolean | string[] } = {}): McpServer {\n const { agents = true, ...rest } = opts\n const names = agents === true ? this.names : agents === false ? [] : agents\n const factories: Record<string, () => Agent> = {}\n for (const name of names) factories[name] = () => this.create(name)\n return new McpServer({ ...rest, agents: factories })\n }\n\n /** URL patterns to `include()`. */\n get urls(): UrlPatterns {\n this._urls ??= this.getUrls()\n return this._urls\n }\n}\n","import { getHost, ImproperlyConfigured, path, tryGetContext, type UrlPatterns } from '@ghuri/core'\nimport {\n type APIRequest,\n APIResponse,\n APIView,\n type AuthenticationClass,\n type BaseAuthentication,\n type BasePermission,\n JSONRenderer,\n type PermissionClass,\n} from '@ghuri/rest'\nimport { Agent, type ToolsInput } from './agent'\nimport { ToolError } from './errors'\nimport { agentsSettings, defaultPermissionClasses } from './settings'\nimport { runTool } from './tools/execute'\nimport { sanitizeToolName } from './tools/schema'\nimport { isToolDecorator, standaloneTool } from './tools/tool'\nimport { type AgentTool, isAgentTool, isToolkit, type ToolContext } from './tools/types'\n\n/** Protocol revisions this server speaks (newest first). */\nexport const MCP_PROTOCOL_VERSIONS = ['2025-11-25', '2025-06-18', '2025-03-26', '2024-11-05'] as const\nexport const MCP_LATEST_PROTOCOL_VERSION = MCP_PROTOCOL_VERSIONS[0]\n\n/** JSON-RPC 2.0 error codes. */\nexport const JSONRPC = {\n PARSE_ERROR: -32700,\n INVALID_REQUEST: -32600,\n METHOD_NOT_FOUND: -32601,\n INVALID_PARAMS: -32602,\n INTERNAL_ERROR: -32603,\n /** Server-defined: authentication / authorization failures. */\n UNAUTHORIZED: -32001,\n} as const\n\nexport type JsonRpcId = string | number | null\n\nexport interface JsonRpcResponse {\n jsonrpc: '2.0'\n id: JsonRpcId\n result?: unknown\n error?: { code: number; message: string; data?: unknown }\n}\n\n/** An `Agent` subclass, or a factory returning a fresh agent. */\nexport type AgentSource = (new () => Agent) | (() => Agent)\n\nfunction isAgentClass(source: AgentSource): source is new () => Agent {\n return source === Agent || source.prototype instanceof Agent\n}\n\n/** A factory for `source`: classes are instantiated with `new`, factories are called. */\nfunction agentFactory(source: AgentSource): () => Agent {\n return isAgentClass(source) ? () => new source() : (source as () => Agent)\n}\n\nexport interface McpServerOptions {\n /** Server name shown to clients (default `'ghuri'`). */\n name?: string\n /** Server version (default `'0.1.0'`). */\n version?: string\n title?: string\n /** Instructions for the client's model (returned by `initialize`). */\n instructions?: string\n /** Tools to expose: toolkits (`ModelTools`, `ViewSetTools`, `RouterTools`), `tool({...execute})`, `AgentTool`s. */\n tools?: ToolsInput\n /** Agents to expose as `ask_<name>` tools: agent classes (`{ support: SupportAgent }`) or factories (`() => new SupportAgent()`). */\n agents?: Record<string, AgentSource>\n /** Authentication (default `AGENTS.AUTHENTICATION_CLASSES`, then REST defaults). */\n authenticationClasses?: AuthenticationClass[]\n /** Access to the endpoint (default `AGENTS.PERMISSION_CLASSES`: `[IsAuthenticated]`). */\n permissionClasses?: PermissionClass[]\n /** Accept browser `Origin`s other than the server's own host / `CSRF_TRUSTED_ORIGINS` (default false). */\n allowAnyOrigin?: boolean\n}\n\nexport interface McpCallContext {\n user: ToolContext['user']\n request?: APIRequest\n signal?: AbortSignal\n}\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v)\n}\n\nfunction errorResponse(id: JsonRpcId, code: number, message: string, data?: unknown): JsonRpcResponse {\n return { jsonrpc: '2.0', id, error: { code, message, ...(data !== undefined ? { data } : {}) } }\n}\n\nfunction asJson(value: unknown): unknown {\n return value === undefined ? null : JSON.parse(JSON.stringify(value))\n}\n\n/**\n * A Model Context Protocol server over **Streamable HTTP** (JSON-RPC 2.0 over POST, JSON responses; no\n * server-initiated SSE stream, so GET answers 405). Implements `initialize`, `ping`, `tools/list`,\n * `tools/call`, empty `resources/list` / `prompts/list`, notifications and batches. Requests are authenticated\n * with REST authentication classes and every tool runs as the authenticated user.\n */\nexport class McpServer {\n readonly opts: McpServerOptions\n\n constructor(opts: McpServerOptions = {}) {\n this.opts = opts\n }\n\n /** All exposed tools (toolkits expanded, agents as `ask_<name>`). */\n getTools(): AgentTool[] {\n const out: AgentTool[] = []\n const add = (entry: unknown, key?: string) => {\n if (isToolDecorator(entry)) out.push(standaloneTool(entry, key))\n else if (isAgentTool(entry)) out.push(entry)\n else if (isToolkit(entry)) out.push(...entry.getTools())\n else throw new TypeError(`MCP tools: unsupported entry ${key ? `'${key}'` : String(entry)}.`)\n }\n const tools = this.opts.tools\n if (Array.isArray(tools)) for (const t of tools) add(t)\n else if (tools) for (const [k, t] of Object.entries(tools)) add(t, k)\n for (const [name, factory] of Object.entries(this.opts.agents ?? {})) out.push(agentTool(name, factory))\n const seen = new Set<string>()\n for (const t of out) {\n if (seen.has(t.name)) throw new ImproperlyConfigured(`MCP server has two tools named '${t.name}'.`)\n seen.add(t.name)\n }\n return out\n }\n\n /** `tools/list` entries. */\n listTools(): Array<Record<string, unknown>> {\n return this.getTools().map((t) => ({\n name: t.name,\n ...(t.annotations?.title ? { title: t.annotations.title } : {}),\n description: t.description,\n inputSchema: t.inputSchema,\n ...(t.outputSchema ? { outputSchema: t.outputSchema } : {}),\n ...(t.annotations ? { annotations: t.annotations } : {}),\n }))\n }\n\n /** `tools/call`: run a tool as `ctx.user`. Tool failures are results with `isError: true`. */\n async callTool(name: string, args: unknown, ctx: McpCallContext): Promise<Record<string, unknown>> {\n const tool = this.getTools().find((t) => t.name === name)\n if (!tool) throw new McpError(JSONRPC.INVALID_PARAMS, `Unknown tool: ${name}`)\n try {\n const out = await runTool(tool, args, { user: ctx.user, request: ctx.request, signal: ctx.signal })\n if (typeof out === 'string') return { content: [{ type: 'text', text: out }], isError: false }\n const json = asJson(out)\n return {\n content: [{ type: 'text', text: JSON.stringify(json) }],\n structuredContent: isPlainObject(json) ? json : { result: json },\n isError: false,\n }\n } catch (err) {\n const e = err instanceof ToolError ? err : new ToolError(String(err))\n const detail = e.detail !== undefined ? `\\n${JSON.stringify(e.detail)}` : ''\n return { content: [{ type: 'text', text: `${e.message}${detail}` }], isError: true }\n }\n }\n\n /** `initialize` result. */\n initializeResult(params: Record<string, unknown>): Record<string, unknown> {\n const requested = typeof params.protocolVersion === 'string' ? params.protocolVersion : undefined\n const protocolVersion =\n requested && (MCP_PROTOCOL_VERSIONS as readonly string[]).includes(requested)\n ? requested\n : MCP_LATEST_PROTOCOL_VERSION\n return {\n protocolVersion,\n capabilities: { tools: { listChanged: false } },\n serverInfo: {\n name: this.opts.name ?? 'ghuri',\n version: this.opts.version ?? '0.1.0',\n ...(this.opts.title ? { title: this.opts.title } : {}),\n },\n ...(this.opts.instructions ? { instructions: this.opts.instructions } : {}),\n }\n }\n\n /** Handle one JSON-RPC message; `null` for notifications and client responses (nothing to send). */\n async handleMessage(message: unknown, ctx: McpCallContext): Promise<JsonRpcResponse | null> {\n if (!isPlainObject(message) || message.jsonrpc !== '2.0') {\n const id = isPlainObject(message) && isValidId(message.id) ? (message.id as JsonRpcId) : null\n return errorResponse(id, JSONRPC.INVALID_REQUEST, 'Invalid Request')\n }\n const hasId = 'id' in message && message.id !== undefined\n if (typeof message.method !== 'string') {\n // A response from the client (to a server request we never send) — ignore.\n if (('result' in message || 'error' in message) && hasId) return null\n return errorResponse(\n isValidId(message.id) ? (message.id as JsonRpcId) : null,\n JSONRPC.INVALID_REQUEST,\n 'Invalid Request',\n )\n }\n if (!hasId) return null // notification (notifications/initialized, notifications/cancelled, …)\n if (!isValidId(message.id) || message.id === null)\n return errorResponse(null, JSONRPC.INVALID_REQUEST, 'Invalid Request: id must be a string or number')\n const id = message.id as JsonRpcId\n const params = message.params === undefined ? {} : message.params\n if (!isPlainObject(params)) return errorResponse(id, JSONRPC.INVALID_PARAMS, 'params must be an object')\n try {\n const result = await this.dispatch(message.method, params, ctx)\n return { jsonrpc: '2.0', id, result }\n } catch (err) {\n if (err instanceof McpError) return errorResponse(id, err.code, err.message, err.data)\n console.error('[ghuri.agents] MCP request failed:', err)\n const debug = !!tryGetContext()?.settings.DEBUG\n return errorResponse(\n id,\n JSONRPC.INTERNAL_ERROR,\n debug && err instanceof Error ? err.message : 'Internal error',\n )\n }\n }\n\n protected async dispatch(\n method: string,\n params: Record<string, unknown>,\n ctx: McpCallContext,\n ): Promise<unknown> {\n switch (method) {\n case 'initialize':\n return this.initializeResult(params)\n case 'ping':\n return {}\n case 'tools/list':\n return { tools: this.listTools() }\n case 'tools/call': {\n if (typeof params.name !== 'string')\n throw new McpError(JSONRPC.INVALID_PARAMS, 'tools/call requires a tool name')\n return this.callTool(params.name, params.arguments ?? {}, ctx)\n }\n case 'resources/list':\n return { resources: [] }\n case 'resources/templates/list':\n return { resourceTemplates: [] }\n case 'prompts/list':\n return { prompts: [] }\n case 'logging/setLevel':\n return {}\n default:\n throw new McpError(JSONRPC.METHOD_NOT_FOUND, `Method not found: ${method}`)\n }\n }\n\n /** Handle a parsed POST body (single message or batch). Returns the HTTP status and JSON body (or none). */\n async handleBody(body: unknown, ctx: McpCallContext): Promise<{ status: number; body?: unknown }> {\n if (Array.isArray(body)) {\n if (!body.length)\n return { status: 400, body: errorResponse(null, JSONRPC.INVALID_REQUEST, 'Empty batch') }\n const responses: JsonRpcResponse[] = []\n for (const m of body) {\n const r = await this.handleMessage(m, ctx)\n if (r) responses.push(r)\n }\n return responses.length ? { status: 200, body: responses } : { status: 202 }\n }\n const r = await this.handleMessage(body, ctx)\n if (!r) return { status: 202 }\n return { status: 200, body: r }\n }\n\n /** The Streamable HTTP endpoint view. */\n asView() {\n return McpView.asView({ mcpServer: this })\n }\n\n /** URL patterns: mount with `path('mcp/', server.urls)`. */\n get urls(): UrlPatterns {\n return [path('', this.asView(), { name: 'mcp' })]\n }\n}\n\n/** A JSON-RPC error raised while dispatching. */\nexport class McpError extends Error {\n constructor(\n readonly code: number,\n message: string,\n readonly data?: unknown,\n ) {\n super(message)\n }\n}\n\nfunction isValidId(id: unknown): boolean {\n return id === null || typeof id === 'string' || (typeof id === 'number' && Number.isFinite(id))\n}\n\n/** An agent exposed as an MCP tool (`ask_<name>`). */\nexport function agentTool(name: string, source: AgentSource): AgentTool {\n const factory = agentFactory(source)\n const probe = factory()\n return {\n name: sanitizeToolName(`ask_${name}`),\n description: probe.getDescription(),\n inputSchema: {\n type: 'object',\n properties: {\n message: { type: 'string', description: 'Your message to the agent.' },\n conversationId: {\n type: 'string',\n description: 'Continue a previous conversation (the conversationId returned by an earlier call).',\n },\n },\n required: ['message'],\n },\n annotations: { title: `Ask ${name}`, readOnlyHint: false, openWorldHint: false },\n parse(input: unknown) {\n if (!isPlainObject(input) || typeof input.message !== 'string' || !input.message.trim())\n throw new ToolError(\"'message' is required.\", { status: 400 })\n if (input.conversationId !== undefined && typeof input.conversationId !== 'string')\n throw new ToolError(\"'conversationId' must be a string.\", { status: 400 })\n return input\n },\n async execute(input: { message: string; conversationId?: string }, ctx: ToolContext) {\n const agent = factory()\n await agent.checkPermissions(ctx.user, ctx.request)\n const r = await agent.run(input.message, {\n user: ctx.user,\n conversationId: input.conversationId ?? null,\n request: ctx.request,\n signal: ctx.signal,\n })\n return { text: r.text, ...(r.conversationId ? { conversationId: r.conversationId } : {}) }\n },\n }\n}\n\nfunction sameOrigin(request: APIRequest, origin: string): boolean {\n let url: URL\n try {\n url = new URL(origin)\n } catch {\n return false\n }\n const host = getHost(request.c)\n if (url.host === host) return true\n const trusted = (tryGetContext()?.settings.CSRF_TRUSTED_ORIGINS as string[] | undefined) ?? []\n return trusted.some(\n (t) =>\n t === origin ||\n (t.includes('*') && new RegExp(`^${t.replace(/[.]/g, '\\\\.').replace('*', '[^/]+')}$`).test(origin)),\n )\n}\n\n/** The Streamable HTTP endpoint (POST JSON-RPC; GET / DELETE → 405). */\nexport class McpView extends APIView {\n declare mcpServer: McpServer\n override rendererClasses = [JSONRenderer]\n\n override getAuthenticators(): BaseAuthentication[] {\n const classes = this.mcpServer.opts.authenticationClasses ?? agentsSettings().AUTHENTICATION_CLASSES\n return classes ? classes.map((A) => new A()) : super.getAuthenticators()\n }\n\n override getPermissions(): BasePermission[] {\n return (this.mcpServer.opts.permissionClasses ?? defaultPermissionClasses()).map((P) => new P())\n }\n\n override performContentNegotiation(request: APIRequest, _force = false): [any, string] {\n return super.performContentNegotiation(request, true)\n }\n\n /** Authentication / permission failures keep their HTTP status (401 + WWW-Authenticate) with a JSON-RPC body. */\n override async handleException(exc: unknown): Promise<APIResponse> {\n const res = await super.handleException(exc)\n const detail = (res.data as any)?.detail\n res.data = errorResponse(\n null,\n res.status === 401 || res.status === 403 ? JSONRPC.UNAUTHORIZED : JSONRPC.INTERNAL_ERROR,\n detail !== undefined && detail !== null ? String(detail) : 'Request failed',\n ) as any\n return res\n }\n\n async post(request: APIRequest): Promise<APIResponse | Response> {\n const origin = request.header('origin')\n if (origin && !this.mcpServer.opts.allowAnyOrigin && !sameOrigin(request, origin)) {\n return new APIResponse(errorResponse(null, JSONRPC.INVALID_REQUEST, 'Origin not allowed'), {\n status: 403,\n })\n }\n const version = request.header('mcp-protocol-version')\n if (version && !(MCP_PROTOCOL_VERSIONS as readonly string[]).includes(version)) {\n return new APIResponse(\n errorResponse(null, JSONRPC.INVALID_REQUEST, `Unsupported MCP-Protocol-Version: ${version}`),\n { status: 400 },\n )\n }\n let body: unknown\n try {\n body = request.data\n } catch {\n return new APIResponse(errorResponse(null, JSONRPC.PARSE_ERROR, 'Parse error'), { status: 400 })\n }\n if (body === undefined || (isPlainObject(body) && !Object.keys(body).length)) {\n return new APIResponse(errorResponse(null, JSONRPC.INVALID_REQUEST, 'Invalid Request'), { status: 400 })\n }\n const { status, body: out } = await this.mcpServer.handleBody(body, {\n user: request.user,\n request,\n signal: request.raw.signal,\n })\n if (out === undefined) return new Response(null, { status })\n return new APIResponse(out, { status })\n }\n\n async get(): Promise<Response> {\n return new Response(null, { status: 405, headers: { Allow: 'POST' } })\n }\n\n async delete(): Promise<Response> {\n return new Response(null, { status: 405, headers: { Allow: 'POST' } })\n }\n}\n","import type { RequestUser } from '@ghuri/core'\nimport {\n FieldFilter,\n ModelSerializer,\n ModelViewSet,\n OrderingFilter,\n PageNumberPagination,\n type PermissionClass,\n SearchFilter,\n} from '@ghuri/rest'\nimport { sanitizeToolName } from './schema'\nimport { type ActionToolSpec, ViewSetTools } from './viewset'\n\nexport type ModelToolAction = 'list' | 'retrieve' | 'create' | 'update' | 'delete'\n\n/** ModelTools action → generated viewset action (`update` is a partial update: only the given fields change). */\nconst ACTIONS: Record<ModelToolAction, string> = {\n list: 'list',\n retrieve: 'retrieve',\n create: 'create',\n update: 'partialUpdate',\n delete: 'destroy',\n}\n\nexport interface ModelToolsOptions {\n /** Tools to generate (default `['list', 'retrieve']`: read-only unless you opt into writes). */\n actions?: ModelToolAction[]\n /** Serializer class (default: a `ModelSerializer` with `fields: '__all__'`). */\n serializer?: any\n /** Scope the queryset to the requesting user: `(qs, user) => qs.filter({ owner: user.pk })`. Applies to\n * every action (list, retrieve, update, delete), so other users' rows are invisible (404). */\n filter?: (qs: any, user: RequestUser) => any\n /** Enable `search` over these fields (SearchFilter lookups: `'title'`, `'^slug'`, `'=email'`). */\n searchFields?: string[]\n /** Fields the model may order by (`ordering=-createdAt`); `'__all__'` for any readable field. */\n orderingFields?: string[] | '__all__'\n /** Default ordering. */\n ordering?: string | string[]\n /** Exact-match filters (FieldFilter): `['status']` or `{ createdAt: ['gte', 'lte'] }`. */\n filterFields?: string[] | Record<string, string[]>\n /** Page size of `list` (default 20; the model may request up to `maxPageSize` with `pageSize`). */\n pageSize?: number\n maxPageSize?: number\n /** REST permission classes checked for every call (default `REST_FRAMEWORK.DEFAULT_PERMISSION_CLASSES`). */\n permissionClasses?: PermissionClass[]\n /** Extra values saved on create / update, e.g. the owner: `(user) => ({ owner: user.pk })`. */\n saveKwargs?: (\n user: RequestUser,\n action: 'create' | 'update',\n ) => Record<string, unknown> | Promise<Record<string, unknown>>\n /** Tool name prefix (default: the model's plural verbose name: `posts`). */\n prefix?: string\n /** Override tool descriptions per action. */\n descriptions?: Partial<Record<ModelToolAction, string>>\n}\n\nfunction defaultSerializer(model: any): any {\n const cls = class extends ModelSerializer {\n static override Meta = { model, fields: '__all__' as const }\n }\n Object.defineProperty(cls, 'name', { value: `${model._meta.objectName}Serializer` })\n return cls\n}\n\n/** Build the ModelViewSet behind a `ModelTools`. */\nfunction buildViewSet(model: any, opts: ModelToolsOptions): any {\n const serializer = opts.serializer ?? defaultSerializer(model)\n const backends: any[] = []\n if (opts.filterFields) backends.push(FieldFilter)\n if (opts.searchFields?.length) backends.push(SearchFilter)\n if (opts.orderingFields || opts.ordering) backends.push(OrderingFilter)\n const pageSize = opts.pageSize ?? 20\n const maxPageSize = opts.maxPageSize ?? Math.max(100, pageSize)\n const Paginator = class AgentPagination extends PageNumberPagination {\n override pageSize = pageSize\n override pageSizeQueryParam = 'pageSize'\n override maxPageSize = maxPageSize\n }\n const ViewSet = class extends ModelViewSet {\n override queryset = model\n override serializerClass = serializer\n override filterBackends = backends\n override paginationClass = Paginator as any\n override searchFields = opts.searchFields\n override orderingFields = opts.orderingFields\n override ordering = opts.ordering\n override filtersetFields = opts.filterFields\n\n constructor() {\n super()\n if (opts.permissionClasses) this.permissionClasses = opts.permissionClasses\n }\n\n override getQueryset(): any {\n const qs = super.getQueryset()\n return opts.filter ? opts.filter(qs, this.request.user) : qs\n }\n\n override async performCreate(serializer: any): Promise<void> {\n await serializer.save(opts.saveKwargs ? await opts.saveKwargs(this.request.user, 'create') : {})\n }\n\n override async performUpdate(serializer: any): Promise<void> {\n await serializer.save(opts.saveKwargs ? await opts.saveKwargs(this.request.user, 'update') : {})\n }\n }\n Object.defineProperty(ViewSet, 'name', { value: `${model._meta.objectName}ToolsViewSet` })\n return ViewSet\n}\n\n/**\n * CRUD tools for a model: `posts_list`, `posts_retrieve`, `posts_create`, `posts_update`, `posts_delete`.\n * Built on a generated `ModelViewSet`, so serializers (validation, read-only fields), permission classes,\n * filters and pagination behave exactly like your REST API, and every call runs as the requesting user.\n *\n * ```ts\n * new ModelTools(Order, {\n * actions: ['list', 'retrieve'],\n * serializer: OrderSerializer,\n * filter: (qs, user) => qs.filter({ customer: user.pk }),\n * searchFields: ['number'], orderingFields: ['createdAt'],\n * })\n * ```\n */\nexport class ModelTools extends ViewSetTools {\n readonly modelClass: any\n readonly modelOptions: ModelToolsOptions\n\n constructor(model: any, opts: ModelToolsOptions = {}) {\n if (!model?._meta) throw new TypeError('ModelTools expects a model class.')\n const prefix =\n opts.prefix ??\n sanitizeToolName(String(model._meta.verboseNamePlural).replace(/\\s+/g, '_').toLowerCase())\n super(buildViewSet(model, opts), { prefix, basename: model._meta.modelName })\n this.modelClass = model\n this.modelOptions = opts\n }\n\n override actionSpecs(): ActionToolSpec[] {\n if (!this.specs) {\n const actions = this.modelOptions.actions ?? ['list', 'retrieve']\n this.specs = actions.map((a) => {\n const action = ACTIONS[a]\n if (!action)\n throw new TypeError(`ModelTools: unknown action '${a}' (use ${Object.keys(ACTIONS).join(', ')}).`)\n return { action, suffix: a, description: this.modelOptions.descriptions?.[a] }\n })\n }\n return this.specs\n }\n}\n","import { ImproperlyConfigured } from '@ghuri/core'\nimport { RouterRegistration, SimpleRouter } from '@ghuri/rest'\nimport { ToolError } from '../errors'\nimport { cleanInputSchema, parametersToProperties, sanitizeToolName, snakeCase } from './schema'\nimport { type AgentTool, type JSONSchema, type ToolAnnotations, type ToolContext, Toolkit } from './types'\n\n/** Friendly aliases accepted in `actions` lists. */\nconst ACTION_ALIASES: Record<string, string> = {\n delete: 'destroy',\n partial_update: 'partialUpdate',\n 'partial-update': 'partialUpdate',\n}\n\nconst STANDARD = new Set(['list', 'create', 'retrieve', 'update', 'partialUpdate', 'destroy'])\n\nexport interface ViewSetToolsOptions {\n /** Actions to expose (`['list', 'retrieve', 'create', 'partialUpdate', 'destroy', 'publish']`; `'delete'` is an\n * alias of `'destroy'`). Default: every routed action of the viewset. */\n actions?: string[]\n /** Tool name prefix (default: the router prefix, or the model's plural name: `posts` → `posts_list`). */\n prefix?: string\n /** Router basename when a viewset class is given (default: derived from `queryset`). */\n basename?: string\n /** Override tool descriptions per action. */\n descriptions?: Record<string, string>\n}\n\nexport interface ActionToolSpec {\n /** Viewset action (`destroy`). */\n action: string\n /** Tool name suffix (`delete`). */\n suffix: string\n description?: string\n}\n\nfunction viewsetPrefix(viewset: any): string {\n let model: any\n try {\n const inst = new viewset()\n model = inst.queryset?.model ?? viewset.queryset?.model\n } catch {\n model = undefined\n }\n if (model?._meta)\n return sanitizeToolName(String(model._meta.verboseNamePlural).replace(/\\s+/g, '_').toLowerCase())\n return sanitizeToolName(snakeCase(String(viewset.name).replace(/ViewSet$|View$/, '')))\n}\n\n/**\n * Tools for a REST viewset, executed through `router.registry[i].invoke()`: the viewset's permission classes,\n * throttles, queryset, filters, pagination, validation and serializers apply exactly as over HTTP, as the\n * requesting user. HTTP errors (403, 404, 400…) become tool errors the model can read.\n *\n * ```ts\n * new ViewSetTools(PostViewSet, { actions: ['list', 'retrieve', 'create'] }) // posts_list, posts_retrieve, …\n * new ViewSetTools(router.registry[0]) // every action of a registration\n * ```\n */\nexport class ViewSetTools extends Toolkit {\n readonly entry: RouterRegistration\n readonly opts: ViewSetToolsOptions\n readonly prefix: string\n protected specs?: ActionToolSpec[]\n\n constructor(target: any, opts: ViewSetToolsOptions = {}) {\n super()\n this.opts = opts\n if (target instanceof RouterRegistration) {\n this.entry = target\n this.prefix = sanitizeToolName(opts.prefix ?? (target.prefix.replace(/\\//g, '_') || target.basename))\n } else if (typeof target === 'function') {\n this.prefix = sanitizeToolName(opts.prefix ?? viewsetPrefix(target))\n const router = new SimpleRouter()\n this.entry = router.register(this.prefix, target, opts.basename ? { basename: opts.basename } : {})\n } else {\n throw new TypeError('ViewSetTools expects a viewset class or a router registry entry.')\n }\n }\n\n /** The (action, tool suffix) pairs to expose. */\n actionSpecs(): ActionToolSpec[] {\n if (this.specs) return this.specs\n const available = this.entry.actions\n const wanted = this.opts.actions ?? available\n this.specs = wanted.map((name) => {\n const action = ACTION_ALIASES[name] ?? name\n if (!available.includes(action)) {\n throw new ImproperlyConfigured(\n `${this.entry.viewset.name} has no routed action '${name}' (available: ${available.join(', ')}).`,\n )\n }\n return { action, suffix: snakeCase(name), description: this.opts.descriptions?.[name] }\n })\n return this.specs\n }\n\n getTools(): AgentTool[] {\n return this.actionSpecs().map((spec) => this.buildTool(spec))\n }\n\n get model(): any {\n return this.entry.model\n }\n\n protected modelNames(): { one: string; many: string } {\n const meta = this.model?._meta\n return {\n one: meta ? String(meta.verboseName) : this.entry.basename,\n many: meta ? String(meta.verboseNamePlural) : this.prefix,\n }\n }\n\n protected lookup(): { kwarg: string; param: string; schema: JSONSchema } {\n const view = this.entry.viewFor('retrieve')\n const field = view.lookupField ?? 'pk'\n const kwarg = view.lookupUrlKwarg ?? field\n const param = kwarg === 'pk' ? 'id' : kwarg\n let schema: JSONSchema = { type: ['integer', 'string'] }\n const meta = this.model?._meta\n const modelField = meta && (field === 'pk' ? meta.pk : meta.getForwardField?.(field))\n if (modelField && typeof modelField.jsonSchema === 'function') {\n try {\n const s = modelField.jsonSchema()\n schema = { type: s.type ?? ['integer', 'string'], ...(s.format ? { format: s.format } : {}) }\n } catch {\n // keep the generic schema\n }\n }\n const { one } = this.modelNames()\n return { kwarg, param, schema: { ...schema, description: `Identifier (${field}) of the ${one}.` } }\n }\n\n protected describe(\n spec: ActionToolSpec,\n endpoint: { detail: boolean; extra: boolean; description?: string },\n ) {\n if (spec.description) return spec.description\n const { one, many } = this.modelNames()\n switch (spec.action) {\n case 'list':\n return `List ${many}. Supports the filters, search, ordering and pagination parameters below; returns the matching ${many}.`\n case 'retrieve':\n return `Get one ${one} by id.`\n case 'create':\n return `Create a ${one}. Returns the created ${one}.`\n case 'update':\n return `Replace a ${one} (all writable fields required). Returns the updated ${one}.`\n case 'partialUpdate':\n return `Update some fields of a ${one}; omitted fields are left unchanged. Returns the updated ${one}.`\n case 'destroy':\n return `Delete a ${one} by id. This cannot be undone.`\n }\n const extra = this.entry.extraActions.find((a) => a.name === spec.action)\n const desc = endpoint.description ?? (extra?.kwargs.description as string | undefined)\n if (desc) return desc\n return endpoint.detail\n ? `Run the '${spec.action}' action on one ${one}.`\n : `Run the '${spec.action}' action on ${many}.`\n }\n\n protected buildTool(spec: ActionToolSpec): AgentTool {\n const endpoints = this.entry.endpoints.filter((e) => e.action === spec.action)\n const endpoint = endpoints[0]\n const methods = [...new Set(endpoints.map((e) => e.method))]\n const extra = !STANDARD.has(spec.action)\n const properties: Record<string, JSONSchema> = {}\n const required: string[] = []\n const lookup = endpoint.detail ? this.lookup() : undefined\n if (lookup) {\n properties[lookup.param] = lookup.schema\n required.push(lookup.param)\n }\n const hasBodyMethod = methods.some((m) => ['POST', 'PUT', 'PATCH'].includes(m))\n let bodyKeys: string[] = []\n let nestData = false\n let queryKeys: string[] = []\n let freeQuery = false\n\n if (hasBodyMethod) {\n const kwargs = this.entry.extraActions.find((a) => a.name === spec.action)?.kwargs ?? {}\n const useSerializer = !extra || kwargs.serializerClass\n const schema = useSerializer\n ? this.entry.jsonSchema(spec.action, { mode: 'input', partial: spec.action === 'partialUpdate' })\n : undefined\n if (schema) {\n const body = cleanInputSchema(schema)\n const props = body.properties as Record<string, JSONSchema>\n nestData = !!lookup && lookup.param in props\n if (nestData) {\n properties.data = { ...body, description: 'Field values.' }\n if ((body.required as string[] | undefined)?.length) required.push('data')\n } else {\n Object.assign(properties, props)\n for (const r of (body.required as string[] | undefined) ?? []) required.push(r)\n bodyKeys = Object.keys(props)\n }\n } else {\n nestData = true\n properties.data = {\n type: 'object',\n description: 'Request body (JSON object), if the action takes one.',\n }\n }\n }\n if (spec.action === 'list') {\n const params = this.listParameters()\n const { properties: qp, required: qr } = parametersToProperties(params)\n for (const [k, v] of Object.entries(qp)) if (!(k in properties)) properties[k] = v\n required.push(...qr.filter((r) => !required.includes(r)))\n queryKeys = Object.keys(qp)\n } else if (methods.includes('GET') && extra) {\n freeQuery = true\n properties.query = { type: 'object', description: 'Optional query string parameters.' }\n }\n if (methods.length > 1) {\n properties.method = { type: 'string', enum: methods, description: 'HTTP method of the action.' }\n }\n\n const inputSchema: JSONSchema = { type: 'object', properties }\n if (required.length) inputSchema.required = required\n const annotations: ToolAnnotations = {\n title: `${this.prefix} ${spec.suffix}`.replace(/_/g, ' '),\n readOnlyHint: methods.every((m) => m === 'GET' || m === 'HEAD'),\n destructiveHint: spec.action === 'destroy' || methods.includes('DELETE'),\n idempotentHint: methods.every((m) => ['GET', 'HEAD', 'PUT', 'DELETE'].includes(m)),\n openWorldHint: false,\n }\n const entry = this.entry\n return {\n name: sanitizeToolName(`${this.prefix}_${spec.suffix}`),\n description: this.describe(spec, endpoint),\n inputSchema,\n annotations,\n parse: (value: unknown) => {\n if (value === undefined || value === null) return {}\n if (typeof value !== 'object' || Array.isArray(value))\n throw new ToolError('Arguments must be an object.')\n const missing = required.filter((r) => (value as any)[r] === undefined)\n if (lookup && missing.includes(lookup.param))\n throw new ToolError(`Missing required argument '${lookup.param}'.`, { status: 400 })\n return value\n },\n execute: async (input: Record<string, any>, ctx: ToolContext) => {\n const args = { ...(input ?? {}) }\n const kwargs: Record<string, unknown> = {}\n if (lookup) {\n kwargs[lookup.kwarg] = args[lookup.param]\n delete args[lookup.param]\n }\n const method = typeof args.method === 'string' ? args.method.toUpperCase() : undefined\n delete args.method\n let query: Record<string, unknown> | undefined\n let data: unknown\n if (spec.action === 'list') {\n query = {}\n for (const k of queryKeys) if (args[k] !== undefined && args[k] !== null) query[k] = args[k]\n } else if (freeQuery && args.query && typeof args.query === 'object') {\n query = args.query\n delete args.query\n }\n if (hasBodyMethod && method !== 'GET') {\n if (nestData) data = args.data ?? {}\n else {\n data = {}\n for (const k of bodyKeys) if (k in args) (data as any)[k] = args[k]\n }\n }\n // Anonymous users are passed as \"no credentials\" so views answer 401-style errors like over HTTP.\n const user = ctx.user?.isAuthenticated ? ctx.user : null\n const res = await entry.invoke(spec.action, { user, kwargs, query, data, method })\n return toolResult(res.status, res.data)\n },\n }\n }\n\n /** OpenAPI query parameters of the list action (filter backends + paginator). */\n protected listParameters(): Array<Record<string, unknown>> {\n const view = this.entry.viewFor('list')\n const out: Array<Record<string, unknown>> = []\n const backends: any[] =\n typeof view.getFilterBackends === 'function' ? view.getFilterBackends() : (view.filterBackends ?? [])\n for (const B of backends) {\n const b = new B()\n if (typeof b.getSchemaOperationParameters === 'function')\n out.push(...b.getSchemaOperationParameters(view))\n }\n const paginator = view.paginator\n if (paginator && typeof paginator.getSchemaOperationParameters === 'function')\n out.push(...paginator.getSchemaOperationParameters(view))\n const seen = new Set<string>()\n return out.filter((p) => {\n const name = String(p.name)\n if (seen.has(name)) return false\n seen.add(name)\n return true\n })\n }\n}\n\n/** Map an `invoke()` result to a tool result, throwing `ToolError` for 4xx / 5xx. */\nexport function toolResult(status: number, data: unknown): unknown {\n if (status >= 400) throw new ToolError(errorMessage(status, data), { status, detail: data })\n if (status === 204 || data === null || data === '') return { success: true, status }\n return data\n}\n\nfunction errorMessage(status: number, data: unknown): string {\n const detail =\n data && typeof data === 'object' && typeof (data as any).detail === 'string'\n ? (data as any).detail\n : typeof data === 'string' && data\n ? data\n : status === 400\n ? `Validation failed: ${JSON.stringify(data)}`\n : undefined\n return `${detail ?? 'Request failed.'} (HTTP ${status})`\n}\n","import type { BaseRouter, RouterRegistration } from '@ghuri/rest'\nimport { type AgentTool, Toolkit } from './types'\nimport { ViewSetTools } from './viewset'\n\nexport interface RouterToolsOptions {\n /** Only these registrations (by prefix or basename), or a predicate. */\n include?: string[] | ((entry: RouterRegistration) => boolean)\n /** Skip these registrations (by prefix or basename), or tool names (`posts_destroy`). */\n exclude?: string[] | ((entry: RouterRegistration) => boolean)\n /** Restrict actions per registration: `{ posts: ['list', 'retrieve'] }`. */\n actions?: Record<string, string[]>\n /** Only read-only actions (GET). */\n readOnly?: boolean\n}\n\nfunction matches(entry: RouterRegistration, spec: string[] | ((e: RouterRegistration) => boolean)): boolean {\n if (typeof spec === 'function') return spec(entry)\n return spec.includes(entry.prefix) || spec.includes(entry.basename)\n}\n\n/**\n * Expose a whole REST API as tools: one `ViewSetTools` per router registration.\n *\n * ```ts\n * new RouterTools(router, { exclude: ['users'], readOnly: true })\n * ```\n */\nexport class RouterTools extends Toolkit {\n constructor(\n readonly router: BaseRouter,\n readonly opts: RouterToolsOptions = {},\n ) {\n super()\n }\n\n /** The `ViewSetTools` of each included registration. */\n toolkits(): ViewSetTools[] {\n const out: ViewSetTools[] = []\n for (const entry of this.router.registry) {\n if (this.opts.include && !matches(entry, this.opts.include)) continue\n if (this.opts.exclude && matches(entry, this.opts.exclude)) continue\n let actions = this.opts.actions?.[entry.prefix] ?? this.opts.actions?.[entry.basename]\n if (this.opts.readOnly) {\n const safe = new Set(entry.endpoints.filter((e) => e.method === 'GET').map((e) => e.action))\n actions = (actions ?? entry.actions).filter((a) => safe.has(a))\n }\n if (actions && !actions.length) continue\n out.push(new ViewSetTools(entry, actions ? { actions } : {}))\n }\n return out\n }\n\n getTools(): AgentTool[] {\n const excluded = Array.isArray(this.opts.exclude) ? new Set(this.opts.exclude) : undefined\n return this.toolkits()\n .flatMap((t) => t.getTools())\n .filter((t) => !excluded?.has(t.name))\n }\n}\n"],"mappings":";;;;;;;AAAA;AAAA,EACE,iBAAAA;AAAA,EAEA,wBAAAC;AAAA,EAEA,iBAAAC;AAAA,OACK;AAEP,SAAS,kBAAkB,wBAAwB;AACnD;AAAA,EACE,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EAEA;AAAA,EAKA;AAAA,EACA;AAAA,OAGK;;;ACvBP,SAAS,QAAAC,aAA8B;;;ACAvC,SAAS,kBAAkB;AAGpB,IAAM,aAAN,cAAyB,WAAW;AAAC;AAMrC,IAAM,YAAN,cAAwB,WAAW;AAAA;AAAA,EAExC;AAAA;AAAA,EAEA;AAAA,EAEA,YAAY,SAAiB,OAA+D,CAAC,GAAG;AAC9F,UAAM,SAAS,EAAE,OAAO,KAAK,MAAM,CAAC;AACpC,SAAK,SAAS,KAAK;AACnB,SAAK,SAAS,KAAK;AAAA,EACrB;AAAA,EAEA,SAAkC;AAChC,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,MAC3D,GAAI,KAAK,WAAW,SAAY,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;AAGO,IAAM,iBAAN,cAA6B,UAAU;AAAA,EAC5C,YAAY,SAAiB,QAAkB;AAC7C,UAAM,SAAS,EAAE,QAAQ,KAAK,OAAO,CAAC;AAAA,EACxC;AACF;AAGO,IAAM,mBAAN,cAA+B,WAAW;AAAC;AAG3C,IAAM,uBAAN,cAAmC,WAAW;AAAC;;;ACzCtD,SAAS,MAAM,qBAAqB;AACpC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,OACK;AAGP,SAAS,YAAwB;AAC/B,QAAM,QAAS,cAAc,GAAG,SAAS,mBAA0C;AACnF,SAAO,KAAK,SAAS,KAAK;AAC5B;AAEA,SAAS,oBAA4B;AACnC,SAAO,OAAO,WAAW;AAC3B;AAEA,SAAS,gBAAyC;AAChD,SAAO,CAAC;AACV;AAGO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,IAAI,IAAI,UAAU,EAAE,YAAY,MAAM,SAAS,mBAAmB,UAAU,MAAM,CAAC;AAAA,EACnF,MAAM,IAAI,WAAW,WAAW;AAAA,IAC9B,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,EACf,CAAC;AAAA,EACD,OAAO,IAAI,UAAU,EAAE,WAAW,KAAK,SAAS,KAAK,CAAC;AAAA,EACtD,OAAO,IAAI,UAAU,EAAE,WAAW,KAAK,OAAO,MAAM,SAAS,GAAG,CAAC;AAAA,EACjE,UAAU,IAAI,UAAU,EAAE,SAAS,eAAe,OAAO,KAAK,CAAC;AAAA,EAC/D,WAAW,IAAI,cAAc,EAAE,YAAY,KAAK,CAAC;AAAA,EACjD,WAAW,IAAI,cAAc,EAAE,SAAS,KAAK,CAAC;AAChD,CAAC,EAAE;AAAA,EAED,OAAO,OAAO,EAAE,UAAU,UAAU,UAAU,CAAC,YAAY,GAAG,aAAa,eAAe;AAAA,EAE1F,WAAmB;AACjB,WAAO,KAAK,SAAS,OAAO,KAAK,EAAE;AAAA,EACrC;AACF;AAGO,IAAM,gBAAgB,CAAC,UAAU,QAAQ,aAAa,MAAM;AAO5D,IAAM,UAAN,cAAsB,MAAM;AAAA,EACjC,cAAc,IAAI,WAAW,MAAM,cAAc,EAAE,UAAU,SAAS,aAAa,WAAW,CAAC;AAAA,EAC/F,MAAM,IAAI,UAAU,EAAE,WAAW,IAAI,SAAS,cAAc,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAqB,EAAE,CAAC;AAAA,EACpG,SAAS,IAAI,UAAU,EAAE,MAAM,KAAK,CAAC;AAAA,EACrC,WAAW,IAAI,cAAc,EAAE,YAAY,KAAK,CAAC;AACnD,CAAC,EAAE;AAAA,EAGD,OAAO,OAAO,EAAE,UAAU,UAAU,UAAU,CAAC,IAAI,GAAG,aAAa,UAAU;AAC/E;;;AF7DO,IAAM,uBAAN,cAAmC,UAAU;AAAA,EAClD,YAAY,SAAiB;AAC3B,UAAM,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,EAChC;AACF;AAGO,SAAS,kBAA2B;AACzC,MAAI;AACF,WAAOC,MAAK,SAASA,MAAK,YAAY,QAAQ;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,QAAQ,MAA+C;AACrE,SAAO,MAAM,kBAAkB,KAAK,KAAK;AAC3C;AAGO,SAAS,QAAQ,cAA4B,MAA+C;AACjG,QAAM,QAAQ,aAAa,UAAU;AACrC,QAAM,KAAK,QAAQ,IAAI;AACvB,MAAI,UAAU,QAAQ,OAAO,KAAM,QAAO,UAAU,QAAQ,OAAO;AACnE,SAAO,OAAO,KAAK,MAAM,OAAO,EAAE;AACpC;AAGA,eAAsB,gBACpB,OACA,IACA,MACuB;AACvB,MAAI,OAA4B;AAChC,MAAI;AACF,WAAO,MAAM,aAAa,QAAQ,OAAO,EAAE,IAAI,OAAO,EAAE,GAAG,MAAM,CAAC,EAAE,MAAM;AAAA,EAC5E,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,CAAC,QAAQ,CAAC,QAAQ,MAAM,IAAI,EAAG,OAAM,IAAI,qBAAqB,iBAAiB,EAAE,cAAc;AACnG,SAAO;AACT;AAGA,eAAsB,mBACpB,OACA,MACA,OAA+D,CAAC,GACzC;AACvB,QAAM,KAAK,QAAQ,IAAI;AACvB,SAAO,aAAa,QAAQ,OAAO;AAAA,IACjC;AAAA,IACA,QAAQ,KAAK,SAAS,IAAI,MAAM,GAAG,GAAG;AAAA,IACtC,UAAU,KAAK,YAAY,CAAC;AAAA,IAC5B,GAAI,OAAO,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;AAAA,EACtC,CAAQ;AACV;AAGA,eAAsB,aAAa,cAA8D;AAC/F,QAAM,KAAK,OAAO,iBAAiB,WAAW,eAAe,OAAO,aAAa,EAAE;AACnF,QAAM,OAAO,MAAM,QAAQ,QAAQ,OAAO,EAAE,cAAc,GAAG,CAAC,EAAE,QAAQ,IAAI;AAC5E,SAAO,KAAK,IAAI,CAAC,OAAY,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,QAAQ,EAAkB;AACpF;AAGA,SAAS,YAAY,SAA2B;AAC9C,SAAO,KAAK;AAAA,IACV,KAAK,UAAU,SAAS,CAAC,IAAI,MAAM;AACjC,UAAI,aAAa,YAAY;AAC3B,YAAI,IAAI;AACR,mBAAW,KAAK,EAAG,MAAK,OAAO,aAAa,CAAC;AAC7C,eAAO,KAAK,CAAC;AAAA,MACf;AACA,UAAI,aAAa,IAAK,QAAO,EAAE,SAAS;AACxC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAGA,eAAsB,aAAa,cAA4B,UAAyC;AACtG,MAAI,CAAC,SAAS,OAAQ;AACtB,QAAM,QAAQ,QAAQ;AAAA,IACpB,SAAS;AAAA,MACP,CAAC,MACC,IAAI,QAAQ;AAAA,QACV,gBAAgB,OAAO,aAAa,EAAE;AAAA,QACtC,MAAM,EAAE;AAAA,QACR,SAAS,YAAY,EAAE,OAAO;AAAA,MAChC,CAAQ;AAAA,IACZ;AAAA,EACF;AACA,QAAM,aAAa,KAAK,EAAE,cAAc,CAAC,WAAW,EAAE,CAAC;AACzD;AAGO,SAAS,UAAU,OAAwC;AAChE,MAAI,OAAO;AACX,MAAI,OAAO,UAAU,SAAU,QAAO;AAAA,OACjC;AACH,UAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACjD,UAAM,IAAI,OAAO;AACjB,QAAI,OAAO,MAAM,SAAU,QAAO;AAAA,aACzB,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,IAAI,CAAC,MAAY,EAAE,SAAS,SAAS,EAAE,OAAO,EAAG,EAAE,KAAK,GAAG;AAAA,EACjG;AACA,SAAO,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AACtC,SAAO,KAAK,SAAS,KAAK,GAAG,KAAK,MAAM,GAAG,EAAE,CAAC,QAAQ;AACxD;;;AGnHA,SAAmB,iBAAAC,sBAAqB;;;ACAxC,SAAS,iBAAAC,sBAAqB;AAE9B,SAAS,uBAAuB;AAoCzB,IAAM,oBAAoB;AAG1B,SAAS,iBAAiC;AAC/C,QAAM,IAAIA,eAAc,GAAG,SAAS;AACpC,SAAQ,KAAK,OAAO,MAAM,WAAW,IAAI,CAAC;AAC5C;AAGO,SAAS,2BAA8C;AAC5D,SAAO,eAAe,EAAE,sBAAsB,CAAC,eAAe;AAChE;;;AD9BA,IAAM,MAAM,uBAAO,IAAI,wBAAwB;AAC/C,IAAM,IAAI;AACV,IAAI,CAAC,EAAE,GAAG,EAAG,GAAE,GAAG,IAAI,oBAAI,IAA6B;AACvD,IAAM,YAA0C,EAAE,GAAG;AAY9C,SAAS,iBAAiB,MAAc,SAAgC;AAC7E,YAAU,IAAI,MAAM,OAAO;AAC7B;AAEO,SAAS,mBAAmB,MAAuB;AACxD,SAAO,UAAU,OAAO,IAAI;AAC9B;AAGO,SAAS,eAAyB;AACvC,SAAO,CAAC,GAAG,UAAU,KAAK,CAAC;AAC7B;AAEA,SAAS,WAAW,MAAkC;AACpD,QAAM,IAAK,WAAmB;AAC9B,SAAO,GAAG,MAAM,IAAI;AACtB;AAEA,SAAS,OAAO,KAAsB,SAAqC;AACzE,QAAM,IAAI,IAAI,OAAO,UAAU,IAAI,MAAM,OAAO,KAAK,WAAW,OAAO;AACvE,SAAO,OAAO,MAAM,YAAY,IAAI,IAAI;AAC1C;AAEA,SAAS,eAAe,KAAa,UAAkB,OAAsC;AAC3F,SAAO,IAAI;AAAA,IACT,QAAQ,QAAQ,gCAAgC,GAAG,0BAA0B,GAAG;AAAA,IAChF,EAAE,MAAM;AAAA,EACV;AACF;AAEA,SAAS,aAAa,QAAiD;AACrE,QAAM,EAAE,QAAQ,IAAI,GAAG,KAAK,IAAI;AAChC,SAAO;AACT;AAKA,iBAAiB,cAAc,OAAO,SAAS,QAAQ;AACrD,QAAM,cAAc,IAAI,SAAS,cAAc;AAC/C,QAAM,UAAU,IAAI,MAAM,WAAW;AACrC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,uBAAuB,WAAW,+CAA+C,WAAW;AAAA,IAC9F;AAAA,EACF;AACA,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,OAAO,qBAAqB;AAAA,EAC1C,SAAS,KAAK;AACZ,UAAM,eAAe,uBAAuB,cAAc,GAAG;AAAA,EAC/D;AACA,SAAO,IAAI,gBAAgB,EAAE,GAAI,aAAa,IAAI,MAAM,GAAc,QAAQ,CAAQ,EAAE,OAAc;AACxG,CAAC;AAED,iBAAiB,aAAa,OAAO,SAAS,QAAQ;AACpD,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,OAAO,mBAAmB;AAAA,EACxC,SAAS,KAAK;AACZ,UAAM,eAAe,qBAAqB,aAAa,GAAG;AAAA,EAC5D;AACA,SAAO,IAAI,gBAAgB,EAAE,GAAG,aAAa,IAAI,MAAM,GAAG,QAAQ,OAAO,KAAK,mBAAmB,EAAE,CAAC;AAAA,IAClG;AAAA,EACF;AACF,CAAC;AAED,iBAAiB,UAAU,OAAO,SAAS,QAAQ;AACjD,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,OAAO,gBAAgB;AAAA,EACrC,SAAS,KAAK;AACZ,UAAM,eAAe,kBAAkB,UAAU,GAAG;AAAA,EACtD;AACA,SAAO,IAAI,aAAa,EAAE,GAAG,aAAa,IAAI,MAAM,GAAG,QAAQ,OAAO,KAAK,gBAAgB,EAAE,CAAC,EAAE,OAAO;AACzG,CAAC;AAGM,SAAS,gBAAgB,OAAyB;AACvD,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,OAAQ,MAAc,YAAY,aACjC,OAAQ,MAAc,eAAe,cAAc,OAAQ,MAAc,aAAa;AAE3F;AAOA,eAAsB,aAAa,OAAuC,KAAmC;AAC3G,QAAM,WAAW,eAAe;AAChC,QAAM,IAAI,SAAS,SAAS;AAC5B,MAAI,CAAC,GAAG;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,IAAI,EAAE,QAAQ,GAAG;AACvB,MAAI,KAAK,GAAG;AACV,UAAM,IAAI;AAAA,MACR,UAAU,CAAC,iDAAiD,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,EACF;AACA,QAAM,OAAO,EAAE,MAAM,GAAG,CAAC;AACzB,QAAM,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7B,QAAM,UAAU,UAAU,IAAI,IAAI;AAClC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,2BAA2B,IAAI,SAAS,CAAC,kBAAkB,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,IACtF;AAAA,EACF;AACA,SAAO,QAAQ,SAAS;AAAA,IACtB,KAAK,OAAOC,eAAc,GAAG,OAAO,CAAC;AAAA,IACrC;AAAA,IACA,QAAQ,SAAS,YAAY,IAAI,KAAK,CAAC;AAAA,EACzC,CAAC;AACH;;;AE1JA;AAAA,EACE;AAAA,EACA,QAAAC;AAAA,EACA;AAAA,EAEA;AAAA,EAEA,iBAAAC;AAAA,OACK;AAgBA,IAAM,iBAAiB;AAc9B,eAAsB,WACpB,OACA,OACA,OAAuB,CAAC,GACc;AACtC,QAAM,OAAO,KAAK,WAAW,eAAe,EAAE,iBAAiB;AAC/D,QAAM,QAAQC,eAAc,GAAG,MAAM,IAAI;AACzC,MAAI,CAAC,SAAS,OAAO,MAAM,SAAS,YAAY;AAC9C,UAAM,IAAI;AAAA,MACR,2BAA2B,IAAI;AAAA,IACjC;AAAA,EACF;AACA,MAAI,iBAAiB,KAAK,kBAAkB;AAC5C,MAAI,CAAC,kBAAkB,MAAM,WAAW,SAAS,gBAAgB,GAAG;AAClE,UAAM,OAAO,MAAM,mBAAmB,MAAM,QAAQ,GAAG,KAAK,MAAM,EAAE,OAAO,UAAU,KAAK,EAAE,CAAC;AAC7F,qBAAiB,OAAO,KAAK,EAAE;AAAA,EACjC;AACA,QAAM,MAAgB;AAAA,IACpB,MAAM;AAAA,IACN,OAAO,MAAM,QAAQ;AAAA,IACrB;AAAA,IACA,QAAQ,QAAQ,KAAK,IAAI;AAAA,IACzB,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;AAAA,IAC3C,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,EAClD;AACA,QAAM,MAAM,KAAK,GAAG;AACpB,SAAO,EAAE,eAAe;AAC1B;AAGA,eAAsB,YAAY,QAAuC;AACvE,MAAI,WAAW,QAAQ,WAAW,OAAW,QAAO;AACpD,QAAM,QAASA,eAAc,GAAG,SAAS,mBAA0C;AACnF,QAAM,QAAQC,MAAK,SAAS,KAAK;AACjC,SAAO,MAAM,QAAQ,IAAI,EAAE,IAAI,OAAO,CAAC;AACzC;AAMO,SAAS,kBAAkB,OAAe,QAA6C;AAC5F,SAAO,QAAQ,OAAO,OAAO,UAAiC;AAC5D,eAAW,OAAO,MAAM,UAAU;AAChC,YAAM,MAAM,IAAI;AAChB,UAAI,CAAC,OAAO,IAAI,SAAS,eAAgB;AACzC,UAAI;AACF,cAAM,QAAQ,OAAO,IAAI,KAAK;AAC9B,cAAM,OAAO,MAAM,YAAY,IAAI,MAAM;AACzC,cAAM,MAAM,IAAI,IAAI,OAAO;AAAA,UACzB;AAAA,UACA,gBAAgB,IAAI,kBAAkB;AAAA,UACtC,SAAS,IAAI;AAAA,QACf,CAAC;AACD,YAAI,IAAI;AAAA,MACV,SAAS,KAAK;AACZ,gBAAQ,MAAM,iCAAiC,IAAI,KAAK,aAAa,GAAG;AACxE,YAAI,MAAM;AAAA,MACZ;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACnGA,SAA4B,WAAW,gBAAgB,iBAAAC,gBAAe,uBAAuB;AAC7F,SAAS,oBAAoB;AAKtB,SAAS,UAAa,KAA+B,IAAgB;AAC1E,MAAI,CAAC,OAAOC,eAAc,MAAM,IAAK,QAAO,GAAG;AAC/C,SAAO,eAAe,KAAK,EAAE;AAC/B;AAEA,SAAS,UAAmB;AAC1B,SAAO,CAAC,CAACA,eAAc,GAAG,SAAS;AACrC;AAOO,SAAS,YAAY,KAAc,UAA8B;AACtE,MAAI,eAAe,UAAW,QAAO;AACrC,MAAI,eAAe,cAAc;AAC/B,WAAO,IAAI,UAAU,GAAG,IAAI,WAAW,iBAAiB,UAAU,IAAI,UAAU,KAAK;AAAA,MACnF,QAAQ,IAAI;AAAA,MACZ,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,eAAe,WAAW;AAC5B,WAAO,IAAI,UAAU,GAAG,IAAI,OAAO,UAAW,IAAY,MAAM,KAAK;AAAA,MACnE,QAAS,IAAY;AAAA,MACrB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,eAAe,iBAAiB;AAClC,UAAM,SAAU,IAAY,eAAgB,IAAY;AACxD,WAAO,IAAI,UAAU,sBAAsB,KAAK,UAAU,UAAU,IAAI,OAAO,CAAC,IAAI;AAAA,MAClF,QAAQ;AAAA,MACR;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,MAAI,eAAe,SAAS,IAAI,SAAS,aAAc,QAAO,IAAI,UAAU,YAAY,EAAE,OAAO,IAAI,CAAC;AACtG,UAAQ,MAAM,uBAAuB,YAAY,EAAE,YAAY,GAAG;AAClE,QAAM,UAAU,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU;AAClE,SAAO,IAAI,UAAU,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAC3D;AAGA,eAAsB,QAAQC,OAAiB,MAAe,KAAoC;AAChG,MAAI;AACF,UAAM,QAAQA,MAAK,QAAQA,MAAK,MAAM,IAAI,IAAK,QAAQ,CAAC;AACxD,WAAO,MAAMA,MAAK,QAAQ,OAAO,GAAG;AAAA,EACtC,SAAS,KAAK;AACZ,UAAM,YAAY,KAAKA,MAAK,IAAI;AAAA,EAClC;AACF;;;ACxDA,SAAS,wBAAAC,6BAA4B;;;ACArC,SAAS,SAAS;AAKX,SAAS,iBAAiB,MAAsB;AACrD,QAAM,IAAI,KACP,QAAQ,oBAAoB,GAAG,EAC/B,QAAQ,OAAO,GAAG,EAClB,QAAQ,YAAY,EAAE;AACzB,UAAQ,KAAK,QAAQ,MAAM,GAAG,EAAE;AAClC;AAGO,SAAS,UAAU,GAAmB;AAC3C,SAAO,EACJ,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,WAAW,GAAG,EACtB,YAAY;AACjB;AAGO,SAAS,YAAY,OAAoC;AAC9D,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,UAAW,SACX,OAAQ,MAAoB,cAAc;AAE9C;AAGO,SAAS,aAAa,OAA4B;AACvD,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AACnF,MAAI,YAAY,KAAK,GAAG;AACtB,UAAM,SAAS,EAAE,aAAa,OAAO,EAAE,IAAI,SAAS,iBAAiB,MAAM,CAAC;AAC5E,WAAO,OAAO;AACd,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,SAAU,QAAO,EAAE,GAAI,MAAqB;AACjE,QAAM,IAAI,UAAU,0DAA0D;AAChF;AAGO,SAAS,WAAW,OAA6C;AACtE,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,CAAC,UAAmB;AACzB,YAAM,MAAM,MAAM,UAAU,SAAS,CAAC,CAAC;AACvC,UAAI,CAAC,IAAI,SAAS;AAChB,cAAM,SAAS,IAAI,MAAM,OAAO,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,GAAG,GAAG,SAAS,EAAE,QAAQ,EAAE;AAC3F,cAAM,UAAU,OAAO,IAAI,CAAC,MAAO,EAAE,OAAO,GAAG,EAAE,IAAI,KAAK,EAAE,OAAO,KAAK,EAAE,OAAQ,EAAE,KAAK,IAAI;AAC7F,cAAM,IAAI,eAAe,sBAAsB,OAAO,IAAI,MAAM;AAAA,MAClE;AACA,aAAO,IAAI;AAAA,IACb;AAAA,EACF;AACA,SAAO,CAAC,UAAmB;AACzB,QAAI,UAAU,UAAa,UAAU,KAAM,QAAO,CAAC;AACnD,QAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK;AAClD,YAAM,IAAI,eAAe,uCAAuC;AAClE,WAAO;AAAA,EACT;AACF;AAGO,SAAS,iBAAiB,QAA4C;AAC3E,MAAI,CAAC,OAAQ,QAAO,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AACrD,QAAM,EAAE,OAAO,IAAI,GAAG,KAAK,IAAI;AAC/B,SAAO,EAAE,GAAG,MAAM,MAAM,UAAU,YAAY,EAAE,GAAK,OAAO,cAAyB,CAAC,EAAG,EAAE;AAC7F;AAGO,SAAS,uBAAuB,QAGrC;AACA,QAAM,aAAyC,CAAC;AAChD,QAAM,WAAqB,CAAC;AAC5B,aAAW,KAAK,QAAQ;AACtB,QAAI,EAAE,MAAM,EAAE,OAAO,QAAS;AAC9B,UAAM,OAAO,OAAO,EAAE,IAAI;AAC1B,eAAW,IAAI,IAAI;AAAA,MACjB,GAAK,EAAE,UAAyB,EAAE,MAAM,SAAS;AAAA,MACjD,GAAI,EAAE,cAAc,EAAE,aAAa,OAAO,EAAE,WAAW,EAAE,IAAI,CAAC;AAAA,IAChE;AACA,QAAI,EAAE,SAAU,UAAS,KAAK,IAAI;AAAA,EACpC;AACA,SAAO,EAAE,YAAY,SAAS;AAChC;;;ADlFO,IAAM,OAAsB,uBAAO,IAAI,mBAAmB;AAE1D,IAAM,eAA8B,uBAAO,IAAI,0BAA0B;AAwBhF,SAAS,KAAK,IAAS,MAAc,MAAyB;AAC5D,MAAI,OAAO,OAAO,WAAY,OAAM,IAAI,UAAU,oCAAoC;AACtF,KAAG,IAAI,IAAI,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,KAAK;AAChD;AAOA,SAAS,uBACP,QACA,KACA,YACgC;AAChC,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,SAAU,QAAO;AAC/D,MAAI,CAAC,UAAW,OAAO,WAAW,YAAY,OAAO,WAAW,WAAa,QAAO;AACpF,MAAI,eAAe,UAAa,eAAe,OAAQ,QAAO;AAC9D,QAAM,OAAO,OAAO,yBAAyB,QAAQ,GAAG;AACxD,SAAO,QAAQ,OAAO,KAAK,UAAU,aAAa,OAAO;AAC3D;AAmBO,SAAS,KACd,MACkB;AAClB,MAAI,CAAC,QAAQ,OAAO,KAAK,gBAAgB;AACvC,UAAM,IAAI,UAAU,yCAAyC;AAC/D,QAAM,aAAa,CAAC,OAAY,SAAe,eAAoC;AACjF,QAAI,cAAc,OAAO,WAAW,UAAU,YAAY;AACxD,WAAK,WAAW,OAAO,OAAO,OAAO,GAAG,IAAmB;AAC3D,aAAO;AAAA,IACT;AACA,QAAI,OAAO,UAAU,YAAY;AAC/B,YAAM,OACJ,WAAW,OAAO,YAAY,YAAY,UAAU,UAAU,OAAO,QAAQ,IAAI,IAAI,MAAM;AAC7F,WAAK,OAAO,MAAM,IAAmB;AACrC,aAAO;AAAA,IACT;AACA,UAAM,SAAS,uBAAuB,OAAO,SAAS,UAAU;AAChE,QAAI,QAAQ;AACV,WAAK,OAAO,OAAO,OAAO,OAAO,GAAG,IAAmB;AACvD,aAAO;AAAA,IACT;AACA,UAAM,IAAI,UAAU,oCAAoC;AAAA,EAC1D;AACA,SAAO,eAAe,WAAW,cAAc,EAAE,OAAO,KAAK,CAAC;AAC9D,SAAO;AACT;AAEO,SAAS,gBAAgB,OAAwC;AACtE,SAAO,OAAO,UAAU,cAAc,gBAAgB;AACxD;AAGO,SAAS,WACd,MACA,MACA,SACW;AACX,SAAO;AAAA,IACL,MAAM,iBAAiB,KAAK,QAAQ,IAAI;AAAA,IACxC,aAAa,KAAK;AAAA,IAClB,aAAa,aAAa,KAAK,KAAK;AAAA,IACpC,GAAI,KAAK,SAAS,EAAE,cAAc,KAAK,OAAO,IAAI,CAAC;AAAA,IACnD,GAAI,KAAK,cAAc,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,IAC5D,OAAO,WAAW,KAAK,KAAK;AAAA,IAC5B;AAAA,EACF;AACF;AAGO,SAAS,eAAe,WAA0B,KAAyB;AAChF,QAAM,OAAO,UAAU,YAAY;AACnC,MAAI,OAAO,KAAK,YAAY,YAAY;AACtC,UAAM,IAAIC;AAAA,MACR,SAAS,KAAK,QAAQ,OAAO,KAAK,WAAW;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI,CAAC,KAAM,OAAM,IAAIA,sBAAqB,uCAAuC,KAAK,WAAW,IAAI;AACrG,SAAO,WAAW,MAAM,MAAM,KAAK,OAAO;AAC5C;AAMO,SAAS,qBAAqB,UAA+B;AAClE,QAAM,MAAM,SAAS;AACrB,QAAM,QAAQ,oBAAI,IAAuB;AACzC,QAAM,QAAe,CAAC;AACtB,WAAS,IAAI,OAAO,eAAe,QAAQ,GAAG,KAAK,MAAM,OAAO,WAAW,IAAI,OAAO,eAAe,CAAC;AACpG,UAAM,QAAQ,CAAC;AACjB,aAAW,SAAS,OAAO;AACzB,eAAW,OAAO,OAAO,oBAAoB,KAAK,GAAG;AACnD,UAAI,QAAQ,cAAe;AAC3B,YAAM,KAAK,OAAO,yBAAyB,OAAO,GAAG,GAAG;AACxD,UAAI,OAAO,OAAO,cAAc,GAAG,IAAI,GAAG;AACxC,cAAM,OAAO,GAAG,IAAI;AACpB,cAAM;AAAA,UACJ;AAAA,UACA,WAAW,KAAK,QAAQ,KAAK,MAAM,CAAC,OAAO,QAAS,SAAiB,GAAG,EAAE,OAAO,GAAG,CAAC;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,cAAqB,CAAC;AAC5B,WAAS,IAAI,KAAK,KAAK,MAAM,SAAS,WAAW,IAAI,OAAO,eAAe,CAAC,EAAG,aAAY,QAAQ,CAAC;AACpG,aAAW,KAAK,aAAa;AAC3B,QAAI,CAAC,OAAO,OAAO,GAAG,OAAO,KAAK,CAAC,EAAE,SAAS,OAAO,EAAE,UAAU,YAAY,MAAM,QAAQ,EAAE,KAAK;AAChG;AACF,eAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,EAAE,KAA4B,GAAG;AACxE,YAAM,OAAgC,gBAAgB,IAAI,IACtD,KAAK,YAAY,IACjB,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,gBAAgB,WAC9D,OACA;AACN,UAAI,CAAC,KAAM;AACX,UAAI,OAAO,KAAK,YAAY,YAAY;AACtC,cAAM,IAAI,KAAK,WAAW,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAO,CAAC;AAC/D;AAAA,MACF;AACA,UAAI,OAAQ,SAAiB,GAAG,MAAM,YAAY;AAChD,cAAM,IAAIA,sBAAqB,GAAG,EAAE,IAAI,UAAU,GAAG,oCAAoC,GAAG,IAAI;AAAA,MAClG;AACA,YAAM;AAAA,QACJ;AAAA,QACA,WAAW,KAAK,QAAQ,KAAK,MAAM,CAAC,OAAO,QAAS,SAAiB,GAAG,EAAE,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;;;AErIO,IAAe,UAAf,MAAuB;AAE9B;AAEO,SAAS,UAAU,OAAkC;AAC1D,SAAO,CAAC,CAAC,SAAS,OAAQ,MAAkB,aAAa;AAC3D;AAEO,SAAS,YAAY,OAAoC;AAC9D,SACE,CAAC,CAAC,SACF,OAAO,UAAU,YACjB,OAAQ,MAAoB,SAAS,YACrC,OAAQ,MAAoB,YAAY,cACxC,OAAQ,MAAoB,gBAAgB;AAEhD;;;AVuDA,SAAS,WAAW,KAAuB;AACzC,QAAM,OAAO,IAAI,KAAK,QAAQ,UAAU,EAAE,KAAK,IAAI,QAAQ;AAC3D,SAAO,KACJ,QAAQ,sBAAsB,OAAO,EACrC,QAAQ,oBAAoB,GAAG,EAC/B,YAAY;AACjB;AAEA,SAAS,UAAU,OAAwB;AACzC,MAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,SAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACjE;AAEA,SAAS,cAAc,SAA+C;AACpE,QAAM,QAAQ,oBAAI,IAA4B;AAC9C,aAAW,QAAQ,SAAS;AAC1B,QAAI,KAAK,SAAS,aAAa;AAC7B,YAAM,IAAI,KAAK,YAAY,EAAE,YAAY,KAAK,YAAY,UAAU,KAAK,UAAU,OAAO,KAAK,MAAM,CAAC;AAAA,IACxG,WAAW,KAAK,SAAS,iBAAiB,KAAK,SAAS,cAAc;AACpE,YAAM,MAAsB,MAAM,IAAI,KAAK,UAAU,KAAK;AAAA,QACxD,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK;AAAA,QACf,OAAO,KAAK;AAAA,MACd;AACA,UAAI,KAAK,SAAS,cAAe,KAAI,SAAS,KAAK;AAAA,UAC9C,KAAI,QAAQ,UAAU,KAAK,KAAK;AACrC,YAAM,IAAI,KAAK,YAAY,GAAG;AAAA,IAChC;AAAA,EACF;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC;AAC3B;AAkBO,IAAM,QAAN,MAAY;AAAA;AAAA,EAEjB,OAAO;AAAA;AAAA,EAEP,OAAO;AAAA;AAAA,EAEP,OAAO;AAAA;AAAA,EAGP;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA,SAAS;AAAA;AAAA,EAET;AAAA;AAAA,EAUA,OAAO,IAEL,OACA,MACyB;AACzB,WAAO,IAAI,KAAK,EAAE,IAAI,OAAO,IAAI;AAAA,EACnC;AAAA,EAEA,UAAkB;AAChB,UAAM,MAAM,KAAK;AACjB,WAAO,KAAK,cAAc,OAAO,OAAO,KAAK,WAAW,IAAI,IAAI,YAAY,WAAc,WAAW,GAAG;AAAA,EAC1G;AAAA,EAEA,iBAAyB;AACvB,UAAM,MAAM,KAAK;AACjB,WAAO,IAAI,eAAe,WAAW,KAAK,QAAQ,CAAC;AAAA,EACrD;AAAA,EAEA,uBAA0C;AACxC,WAAO,KAAK,qBAAqB,yBAAyB;AAAA,EAC5D;AAAA;AAAA,EAGA,MAAM,gBAAgB,KAAmD;AACvE,UAAM,IAAI,KAAK;AACf,WAAO,OAAO,MAAM,aAAa,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI;AAAA,EAC7D;AAAA;AAAA,EAGA,WAAwB;AACtB,UAAM,MAAmB,CAAC;AAC1B,UAAM,MAAM,CAAC,OAAgB,QAAiB;AAC5C,UAAI,gBAAgB,KAAK,EAAG,KAAI,KAAK,eAAe,OAAO,GAAG,CAAC;AAAA,eACtD,YAAY,KAAK,EAAG,KAAI,KAAK,OAAO,CAAC,MAAM,OAAO,EAAE,GAAG,OAAO,MAAM,IAAI,IAAI,KAAK;AAAA,eACjF,UAAU,KAAK,EAAG,KAAI,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA;AAErD,cAAM,IAAIC;AAAA,UACR,GAAG,KAAK,YAAY,IAAI,6BAA6B,MAAM,IAAI,GAAG,MAAM,OAAO,KAAK,CAAC;AAAA,QACvF;AAAA,IACJ;AACA,UAAM,QAAQ,KAAK;AACnB,QAAI,MAAM,QAAQ,KAAK,EAAG,YAAW,KAAK,MAAO,KAAI,CAAC;AAAA,aAC7C,SAAS,OAAO,UAAU,SAAU,YAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,KAAI,GAAG,CAAC;AACjG,QAAI,KAAK,GAAG,qBAAqB,IAAI,CAAC;AACtC,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,KAAK;AACnB,UAAI,KAAK,IAAI,EAAE,IAAI;AACjB,cAAM,IAAIA,sBAAqB,GAAG,KAAK,YAAY,IAAI,yBAAyB,EAAE,IAAI,IAAI;AAC5F,WAAK,IAAI,EAAE,IAAI;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAM,iBAAiB,MAAmB,SAAqC;AAC7E,UAAM,MAAW,WAAW,EAAE,MAAM,MAAM,MAAM,QAAQ,QAAQ,yBAAyB,KAAK;AAC9F,eAAW,KAAK,KAAK,qBAAqB,GAAG;AAC3C,YAAM,IAAI,IAAI,EAAE;AAChB,UAAI,CAAE,MAAM,EAAE,cAAc,KAAK,IAAI,GAAI;AACvC,YAAI,CAAC,KAAK,gBAAiB,OAAM,IAAI,iBAAiB;AACtD,cAAM,IAAI,iBAAkB,EAAE,WAAmB,MAAM,EAAE,QAAQ,IAAI;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,aAAa,KAAsB,QAAqB,KAAK,SAAS,GAAY;AAChF,UAAM,QAAQC,eAAc;AAC5B,UAAM,MAAe,CAAC;AACtB,eAAW,KAAK,OAAO;AACrB,UAAI,EAAE,IAAI,IAAI,OAAO;AAAA,QACnB,aAAa,EAAE;AAAA,QACf,aAAa,WAAW,EAAE,aAA4B;AAAA,UACpD,UAAU,CAAC,UAAmB;AAC5B,gBAAI;AACF,qBAAO,EAAE,SAAS,MAAM,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,MAAM;AAAA,YAClE,SAAS,OAAO;AACd,qBAAO,EAAE,SAAS,OAAO,OAAO,YAAY,OAAO,EAAE,IAAI,EAAE;AAAA,YAC7D;AAAA,UACF;AAAA,QACF,CAAC;AAAA,QACD,SAAS,CAAC,OAAgB,SACxB,UAAU,OAAO,YAAY;AAC3B,gBAAM,UAAuB;AAAA,YAC3B,MAAM,IAAI;AAAA,YACV,OAAO;AAAA,YACP,gBAAgB,IAAI;AAAA,YACpB,YAAY,KAAK;AAAA,YACjB,QAAQ,KAAK,eAAe,IAAI;AAAA,YAChC,SAAS,IAAI;AAAA,UACf;AACA,cAAI;AACF,kBAAM,KAAK,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,KAAK,YAAY,MAAM,GAAG,GAAG;AACrF,mBAAO,MAAM,EAAE,QAAQ,OAAO,OAAO;AAAA,UACvC,SAAS,KAAK;AACZ,kBAAM,YAAY,KAAK,EAAE,IAAI;AAAA,UAC/B;AAAA,QACF,CAAC;AAAA,MACL,CAAQ;AAAA,IACV;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAgB,QAAQ,OAAmB,MAAqC;AAC9E,UAAM,OAAO,KAAK,QAAQC;AAC1B,QAAI,KAAK,iBAAkB,OAAM,KAAK,iBAAiB,MAAM,KAAK,OAAO;AAEzE,UAAM,QAAQ,MAAM,aAAa,KAAK,KAAK;AAC3C,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,YAAY,KAAK,WAAW,KAAK,WAAW,SAAS,gBAAgB;AAC3E,QAAI;AACJ,QAAI,UAA0B,CAAC;AAC/B,QAAI,KAAK,gBAAgB;AACvB,UAAI,CAAC,gBAAgB,GAAG;AACtB,cAAM,IAAIF;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,qBAAe,MAAM,gBAAgB,WAAW,KAAK,gBAAgB,IAAI;AACzE,gBAAU,MAAM,aAAa,YAAY;AAAA,IAC3C,WAAW,WAAW;AACpB,qBAAe,MAAM,mBAAmB,WAAW,MAAM,EAAE,OAAO,KAAK,SAAS,UAAU,KAAK,EAAE,CAAC;AAAA,IACpG;AACA,UAAM,cACJ,OAAO,UAAU,WAAW,CAAC,EAAE,MAAM,QAAQ,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK;AAC5E,UAAM,MAAuB;AAAA,MAC3B,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB,eAAe,OAAO,aAAa,EAAE,IAAI;AAAA,MACzD,UAAU,CAAC,GAAG,SAAS,GAAG,WAAW;AAAA,MACrC;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK,WAAW,CAAC;AAAA,IAC1B;AACA,UAAM,KAAK,YAAY,GAAG;AAC1B,UAAM,eAAe,MAAM,KAAK,gBAAgB,GAAG;AACnD,WAAO,EAAE,KAAK,OAAO,cAAc,OAAO,KAAK,aAAa,GAAG,GAAG,OAAOC,eAAc,EAAE;AAAA,EAC3F;AAAA,EAEU,aAAa,GAAsC;AAC3D,WAAO;AAAA,MACL,OAAO,EAAE;AAAA,MACT,GAAI,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,MACzD,UAAU,EAAE,IAAI;AAAA,MAChB,OAAO,EAAE;AAAA,MACT,UAAU,YAAY,KAAK,YAAY,eAAe,EAAE,aAAa,iBAAiB;AAAA,MACtF,GAAI,KAAK,gBAAgB,SAAY,EAAE,aAAa,KAAK,YAAY,IAAI,CAAC;AAAA,MAC1E,GAAI,KAAK,oBAAoB,SAAY,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;AAAA,MACtF,GAAI,KAAK,kBAAkB,EAAE,iBAAiB,KAAK,gBAAgB,IAAI,CAAC;AAAA,MACxE,GAAI,EAAE,IAAI,SAAS,EAAE,aAAa,EAAE,IAAI,OAAO,IAAI,CAAC;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAgB,OACd,GACA,GAQyB;AACzB,UAAM,WAAW,CAAC,GAAG,EAAE,IAAI,aAAa,GAAG,EAAE,gBAAgB;AAC7D,QAAI,EAAE,IAAI,aAAc,OAAM,aAAa,EAAE,IAAI,cAAc,QAAQ;AACvE,UAAM,SAAyB;AAAA,MAC7B,MAAM,EAAE;AAAA,MACR;AAAA,MACA,WAAW,cAAc,EAAE,OAAO;AAAA,MAClC,OAAO,EAAE;AAAA,MACT,cAAc,EAAE;AAAA,MAChB,OAAO,EAAE;AAAA,MACT,gBAAgB,EAAE,IAAI;AAAA,IACxB;AACA,UAAM,KAAK,WAAW,QAAQ,EAAE,GAAG;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,OAAmB,OAAmB,CAAC,GAA4B;AAC3E,UAAM,IAAI,MAAM,KAAK,QAAQ,OAAO,IAAI;AACxC,UAAM,MAAM,MAAM,aAAa,KAAK,aAAa,CAAC,CAAQ;AAC1D,WAAO,KAAK,OAAO,GAAG;AAAA,MACpB,MAAM,IAAI;AAAA,MACV,kBAAkB,IAAI;AAAA,MACtB,SAAS,IAAI;AAAA,MACb,OAAO,IAAI;AAAA,MACX,cAAc,IAAI;AAAA,MAClB,OAAO,IAAI,MAAM;AAAA,IACnB,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,OAAmB,OAAuB,CAAC,GAAyC;AAChG,WAAO,WAAW,MAAM,OAAO,IAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,OAAmB,OAAmB,CAAC,GAAyB;AAC3E,UAAM,IAAI,MAAM,KAAK,QAAQ,OAAO,IAAI;AACxC,UAAM,SAAS,WAAW,KAAK,aAAa,CAAC,CAAQ;AACrD,UAAM,QAAQ,YAAY;AACxB,YAAM,CAAC,MAAM,kBAAkB,SAAS,OAAO,cAAc,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,QACtF,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,QACP,OAAO;AAAA,MACT,CAAC;AACD,aAAO;AAAA,QAAU,EAAE;AAAA,QAAO,MACxB,KAAK,OAAO,GAAG;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,OAAO,MAAM;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF,GAAG;AACH,SAAK,MAAM,MAAM;AAAA,IAAC,CAAC;AACnB,MAAE,OAAO,cAAc,UAAU,KAAK,MAAM,MAAM;AAAA,IAAC,CAAC,CAAC;AACrD,WAAO,IAAI,YAAY,QAAQ,MAAM,EAAE,IAAI,cAAc;AAAA,EAC3D;AACF;AAGO,IAAM,cAAN,MAAkB;AAAA,EACvB,YAEW,QAEA,MACA,gBACT;AAJS;AAEA;AACA;AAAA,EACR;AAAA,EAJQ;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAIX,IAAI,aAA6D;AAC/D,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAAoD;AAClD,UAAM,iBAAiB,KAAK;AAC5B,UAAM,OAAO,KAAK;AAClB,UAAM,SAAS,KAAK,OAAO,kBAAkB;AAAA,MAC3C,iBAAiB,CAAC,EAAE,KAAK,MACvB,KAAK,SAAS,WAAW,iBAAiB,EAAE,eAAe,IAAI;AAAA,MACjE,SAAS,CAAC,UAAmB,UAAU,KAAK;AAAA,IAC9C,CAAQ;AACR,WAAO,OAAO;AAAA,MACZ,IAAI,gBAAgD;AAAA,QAClD,MAAM,MAAM,YAAY;AACtB,cAAI;AACF,kBAAM;AAAA,UACR,SAAS,KAAK;AACZ,uBAAW,QAAQ,EAAE,MAAM,SAAS,WAAW,UAAU,GAAG,EAAE,CAAmB;AAAA,UACnF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA,EAGA,0BAA0B,OAA8D,CAAC,GAAa;AACpG,WAAO,8BAA8B;AAAA,MACnC,QAAQ,KAAK;AAAA,MACb,SAAS;AAAA,QACP,GAAI,KAAK,iBAAiB,EAAE,qBAAqB,KAAK,eAAe,IAAI,CAAC;AAAA,QAC1E,GAAI,KAAK,WAAW,CAAC;AAAA,MACvB;AAAA,MACA,QAAQ,KAAK,kBAAkB;AAAA,IACjC,CAAC;AAAA,EACH;AACF;;;AW/eA,SAAS,WAAW,iBAAAE,sBAAqB;AACzC,SAAS,aAAAC,YAAW,4BAA4B;;;ACDhD;AAAA;AAAA;AAAA;AAAA;;;ACCA,SAAS,WAAW,cAAc,WAAW;AAE7C,IAAO,kBAAQ,IAAI,UAAU;AAAA,EAC3B,SAAS;AAAA,EACT,cAAc,CAAC,CAAC,QAAQ,cAAc,CAAC;AAAA,EACvC,YAAY;AAAA,IACV,IAAI,YAAY;AAAA,MACd,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,IAAI;AAAA,UACF,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,SAAS,EAAE,UAAU,oBAAoB;AAAA,UACzC,UAAU;AAAA,QACZ;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,UAAU;AAAA,UACV,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,UACT,aAAa;AAAA,QACf;AAAA,QACA,OAAO,EAAE,MAAM,aAAa,WAAW,KAAK,SAAS,KAAK;AAAA,QAC1D,OAAO,EAAE,MAAM,aAAa,WAAW,KAAK,OAAO,MAAM,SAAS,GAAG;AAAA,QACrE,UAAU,EAAE,MAAM,aAAa,OAAO,MAAM,SAAS,EAAE,UAAU,gBAAgB,EAAE;AAAA,QACnF,WAAW,EAAE,MAAM,iBAAiB,YAAY,KAAK;AAAA,QACrD,WAAW,EAAE,MAAM,iBAAiB,SAAS,KAAK;AAAA,MACpD;AAAA,MACA,SAAS,EAAE,UAAU,CAAC,YAAY,GAAG,aAAa,eAAe;AAAA,IACnE,CAAC;AAAA,IACD,IAAI,YAAY;AAAA,MACd,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,IAAI,EAAE,MAAM,gBAAgB,YAAY,KAAK;AAAA,QAC7C,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,IAAI;AAAA,UACJ,UAAU;AAAA,UACV,SAAS;AAAA,UACT,aAAa;AAAA,QACf;AAAA,QACA,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,WAAW;AAAA,UACX,SAAS;AAAA,YACP,CAAC,UAAU,QAAQ;AAAA,YACnB,CAAC,QAAQ,MAAM;AAAA,YACf,CAAC,aAAa,WAAW;AAAA,YACzB,CAAC,QAAQ,MAAM;AAAA,UACjB;AAAA,QACF;AAAA,QACA,SAAS,EAAE,MAAM,aAAa,MAAM,KAAK;AAAA,QACzC,WAAW,EAAE,MAAM,iBAAiB,YAAY,KAAK;AAAA,MACvD;AAAA,MACA,SAAS,EAAE,UAAU,CAAC,IAAI,GAAG,aAAa,UAAU;AAAA,IACtD,CAAC;AAAA,EACH;AACF,CAAC;;;ADtDM,IAAM,aAAa;AAAA,EACxB,gBAAgB;AAClB;;;ADCA,SAAS,yBAAkD;AACzD,QAAM,QAAQC,eAAc,GAAG,SAAS;AACxC,MAAI,CAAC,SAAS,MAAM,YAAY,MAAM,YAAa,QAAO;AAC1D,QAAM,UAAU,MAAM,MAAM,GAAG,EAAE,CAAC;AAClC,QAAM,MAAiC,CAAC;AACxC,aAAW,CAAC,MAAM,CAAC,KAAK,qBAAqB,kBAAgB,KAAK,CAAC,GAAG;AACpE,UAAM,aAAa,EAAE,WAAW,IAAI,CAAC,OAAY;AAC/C,UAAI,CAAC,GAAG,OAAQ,QAAO;AACvB,YAAM,SAAS,OAAO;AAAA,QACpB,OAAO,QAAQ,GAAG,MAA6B,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAC/D,gBAAM,KAAK,GAAG,SAAS,MAAM,GAAG;AAChC,cAAI,OAAO,OAAO,YAAY,GAAG,YAAY,MAAM,YAAa,QAAO,CAAC,GAAG,CAAC;AAC5E,iBAAO,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,MAAM,CAAC;AAAA,QAC7F,CAAC;AAAA,MACH;AACA,aAAO,OAAO,OAAO,OAAO,OAAO,OAAO,eAAe,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC;AAAA,IAC/E,CAAC;AACD,UAAM,eAAe,EAAE,aAAa,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM;AACjE,QAAI,CAAC,aAAa,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,OAAO,EAAG,cAAa,KAAK,CAAC,SAAS,WAAW,CAAU;AAClG,UAAM,UAAU,IAAIC,WAAU,EAAE,cAAc,YAAY,SAAS,EAAE,QAAQ,CAAC;AAC9E,YAAQ,OAAO,EAAE,QAAQ;AACzB,QAAI,QAAQ,IAAI,IAAI;AAAA,EACtB;AACA,SAAO,EAAE,YAAY,IAAI;AAC3B;AAGA,SAAS,UAA8B;AACrC,QAAM,OAAO;AACb,MAAI,CAAC,KAAK,WAAW,CAAC,YAAY,KAAK,KAAK,OAAO,KAAK,CAAC,aAAa,KAAK,KAAK,YAAY,EAAE;AAC5F,WAAO;AACT,SAAO,KAAK;AACd;AAOO,IAAM,eAAN,cAA2B,UAAU;AAAA,EAC1C,OAAO;AAAA,EACE,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO,QAAQ;AAAA,EACf,aAAa,uBAAuB;AAAA,EACpC,SAAS,EAAE,cAAc,QAAQ;AAC5C;;;AGvDA,SAAS,wBAAAC,uBAAsB,QAAAC,OAAM,iBAAAC,sBAAuC;AAC5E;AAAA,EACE,gBAAAC;AAAA,EAEA,eAAAC;AAAA,EACA,WAAAC;AAAA,EAIA,gBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,OACd;;;ACbP,SAAS,SAAS,wBAAAC,uBAAsB,MAAM,iBAAAC,sBAAuC;AACrF;AAAA,EAEE;AAAA,EACA;AAAA,EAIA;AAAA,OAEK;AAUA,IAAM,wBAAwB,CAAC,cAAc,cAAc,cAAc,YAAY;AACrF,IAAM,8BAA8B,sBAAsB,CAAC;AAG3D,IAAM,UAAU;AAAA,EACrB,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA;AAAA,EAEhB,cAAc;AAChB;AAcA,SAAS,aAAa,QAAgD;AACpE,SAAO,WAAW,SAAS,OAAO,qBAAqB;AACzD;AAGA,SAAS,aAAa,QAAkC;AACtD,SAAO,aAAa,MAAM,IAAI,MAAM,IAAI,OAAO,IAAK;AACtD;AA4BA,SAAS,cAAc,GAA0C;AAC/D,SAAO,CAAC,CAAC,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC;AACzD;AAEA,SAAS,cAAc,IAAe,MAAc,SAAiB,MAAiC;AACpG,SAAO,EAAE,SAAS,OAAO,IAAI,OAAO,EAAE,MAAM,SAAS,GAAI,SAAS,SAAY,EAAE,KAAK,IAAI,CAAC,EAAG,EAAE;AACjG;AAEA,SAAS,OAAO,OAAyB;AACvC,SAAO,UAAU,SAAY,OAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACtE;AAQO,IAAM,YAAN,MAAgB;AAAA,EACZ;AAAA,EAET,YAAY,OAAyB,CAAC,GAAG;AACvC,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,WAAwB;AACtB,UAAM,MAAmB,CAAC;AAC1B,UAAM,MAAM,CAAC,OAAgB,QAAiB;AAC5C,UAAI,gBAAgB,KAAK,EAAG,KAAI,KAAK,eAAe,OAAO,GAAG,CAAC;AAAA,eACtD,YAAY,KAAK,EAAG,KAAI,KAAK,KAAK;AAAA,eAClC,UAAU,KAAK,EAAG,KAAI,KAAK,GAAG,MAAM,SAAS,CAAC;AAAA,UAClD,OAAM,IAAI,UAAU,gCAAgC,MAAM,IAAI,GAAG,MAAM,OAAO,KAAK,CAAC,GAAG;AAAA,IAC9F;AACA,UAAM,QAAQ,KAAK,KAAK;AACxB,QAAI,MAAM,QAAQ,KAAK,EAAG,YAAW,KAAK,MAAO,KAAI,CAAC;AAAA,aAC7C,MAAO,YAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,EAAG,KAAI,GAAG,CAAC;AACpE,eAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,KAAK,UAAU,CAAC,CAAC,EAAG,KAAI,KAAK,UAAU,MAAM,OAAO,CAAC;AACvG,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,KAAK;AACnB,UAAI,KAAK,IAAI,EAAE,IAAI,EAAG,OAAM,IAAIC,sBAAqB,mCAAmC,EAAE,IAAI,IAAI;AAClG,WAAK,IAAI,EAAE,IAAI;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAA4C;AAC1C,WAAO,KAAK,SAAS,EAAE,IAAI,CAAC,OAAO;AAAA,MACjC,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,aAAa,QAAQ,EAAE,OAAO,EAAE,YAAY,MAAM,IAAI,CAAC;AAAA,MAC7D,aAAa,EAAE;AAAA,MACf,aAAa,EAAE;AAAA,MACf,GAAI,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,MACzD,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,IACxD,EAAE;AAAA,EACJ;AAAA;AAAA,EAGA,MAAM,SAAS,MAAc,MAAe,KAAuD;AACjG,UAAMC,QAAO,KAAK,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACxD,QAAI,CAACA,MAAM,OAAM,IAAI,SAAS,QAAQ,gBAAgB,iBAAiB,IAAI,EAAE;AAC7E,QAAI;AACF,YAAM,MAAM,MAAM,QAAQA,OAAM,MAAM,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,QAAQ,IAAI,OAAO,CAAC;AAClG,UAAI,OAAO,QAAQ,SAAU,QAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,IAAI,CAAC,GAAG,SAAS,MAAM;AAC7F,YAAM,OAAO,OAAO,GAAG;AACvB,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,IAAI,EAAE,CAAC;AAAA,QACtD,mBAAmB,cAAc,IAAI,IAAI,OAAO,EAAE,QAAQ,KAAK;AAAA,QAC/D,SAAS;AAAA,MACX;AAAA,IACF,SAAS,KAAK;AACZ,YAAM,IAAI,eAAe,YAAY,MAAM,IAAI,UAAU,OAAO,GAAG,CAAC;AACpE,YAAM,SAAS,EAAE,WAAW,SAAY;AAAA,EAAK,KAAK,UAAU,EAAE,MAAM,CAAC,KAAK;AAC1E,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,CAAC,GAAG,SAAS,KAAK;AAAA,IACrF;AAAA,EACF;AAAA;AAAA,EAGA,iBAAiB,QAA0D;AACzE,UAAM,YAAY,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBAAkB;AACxF,UAAM,kBACJ,aAAc,sBAA4C,SAAS,SAAS,IACxE,YACA;AACN,WAAO;AAAA,MACL;AAAA,MACA,cAAc,EAAE,OAAO,EAAE,aAAa,MAAM,EAAE;AAAA,MAC9C,YAAY;AAAA,QACV,MAAM,KAAK,KAAK,QAAQ;AAAA,QACxB,SAAS,KAAK,KAAK,WAAW;AAAA,QAC9B,GAAI,KAAK,KAAK,QAAQ,EAAE,OAAO,KAAK,KAAK,MAAM,IAAI,CAAC;AAAA,MACtD;AAAA,MACA,GAAI,KAAK,KAAK,eAAe,EAAE,cAAc,KAAK,KAAK,aAAa,IAAI,CAAC;AAAA,IAC3E;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cAAc,SAAkB,KAAsD;AAC1F,QAAI,CAAC,cAAc,OAAO,KAAK,QAAQ,YAAY,OAAO;AACxD,YAAMC,MAAK,cAAc,OAAO,KAAK,UAAU,QAAQ,EAAE,IAAK,QAAQ,KAAmB;AACzF,aAAO,cAAcA,KAAI,QAAQ,iBAAiB,iBAAiB;AAAA,IACrE;AACA,UAAM,QAAQ,QAAQ,WAAW,QAAQ,OAAO;AAChD,QAAI,OAAO,QAAQ,WAAW,UAAU;AAEtC,WAAK,YAAY,WAAW,WAAW,YAAY,MAAO,QAAO;AACjE,aAAO;AAAA,QACL,UAAU,QAAQ,EAAE,IAAK,QAAQ,KAAmB;AAAA,QACpD,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,CAAC,UAAU,QAAQ,EAAE,KAAK,QAAQ,OAAO;AAC3C,aAAO,cAAc,MAAM,QAAQ,iBAAiB,gDAAgD;AACtG,UAAM,KAAK,QAAQ;AACnB,UAAM,SAAS,QAAQ,WAAW,SAAY,CAAC,IAAI,QAAQ;AAC3D,QAAI,CAAC,cAAc,MAAM,EAAG,QAAO,cAAc,IAAI,QAAQ,gBAAgB,0BAA0B;AACvG,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,SAAS,QAAQ,QAAQ,QAAQ,GAAG;AAC9D,aAAO,EAAE,SAAS,OAAO,IAAI,OAAO;AAAA,IACtC,SAAS,KAAK;AACZ,UAAI,eAAe,SAAU,QAAO,cAAc,IAAI,IAAI,MAAM,IAAI,SAAS,IAAI,IAAI;AACrF,cAAQ,MAAM,sCAAsC,GAAG;AACvD,YAAM,QAAQ,CAAC,CAACC,eAAc,GAAG,SAAS;AAC1C,aAAO;AAAA,QACL;AAAA,QACA,QAAQ;AAAA,QACR,SAAS,eAAe,QAAQ,IAAI,UAAU;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAgB,SACd,QACA,QACA,KACkB;AAClB,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,KAAK,iBAAiB,MAAM;AAAA,MACrC,KAAK;AACH,eAAO,CAAC;AAAA,MACV,KAAK;AACH,eAAO,EAAE,OAAO,KAAK,UAAU,EAAE;AAAA,MACnC,KAAK,cAAc;AACjB,YAAI,OAAO,OAAO,SAAS;AACzB,gBAAM,IAAI,SAAS,QAAQ,gBAAgB,iCAAiC;AAC9E,eAAO,KAAK,SAAS,OAAO,MAAM,OAAO,aAAa,CAAC,GAAG,GAAG;AAAA,MAC/D;AAAA,MACA,KAAK;AACH,eAAO,EAAE,WAAW,CAAC,EAAE;AAAA,MACzB,KAAK;AACH,eAAO,EAAE,mBAAmB,CAAC,EAAE;AAAA,MACjC,KAAK;AACH,eAAO,EAAE,SAAS,CAAC,EAAE;AAAA,MACvB,KAAK;AACH,eAAO,CAAC;AAAA,MACV;AACE,cAAM,IAAI,SAAS,QAAQ,kBAAkB,qBAAqB,MAAM,EAAE;AAAA,IAC9E;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WAAW,MAAe,KAAkE;AAChG,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,UAAI,CAAC,KAAK;AACR,eAAO,EAAE,QAAQ,KAAK,MAAM,cAAc,MAAM,QAAQ,iBAAiB,aAAa,EAAE;AAC1F,YAAM,YAA+B,CAAC;AACtC,iBAAW,KAAK,MAAM;AACpB,cAAMC,KAAI,MAAM,KAAK,cAAc,GAAG,GAAG;AACzC,YAAIA,GAAG,WAAU,KAAKA,EAAC;AAAA,MACzB;AACA,aAAO,UAAU,SAAS,EAAE,QAAQ,KAAK,MAAM,UAAU,IAAI,EAAE,QAAQ,IAAI;AAAA,IAC7E;AACA,UAAM,IAAI,MAAM,KAAK,cAAc,MAAM,GAAG;AAC5C,QAAI,CAAC,EAAG,QAAO,EAAE,QAAQ,IAAI;AAC7B,WAAO,EAAE,QAAQ,KAAK,MAAM,EAAE;AAAA,EAChC;AAAA;AAAA,EAGA,SAAS;AACP,WAAO,QAAQ,OAAO,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AAAA;AAAA,EAGA,IAAI,OAAoB;AACtB,WAAO,CAAC,KAAK,IAAI,KAAK,OAAO,GAAG,EAAE,MAAM,MAAM,CAAC,CAAC;AAAA,EAClD;AACF;AAGO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC,YACW,MACT,SACS,MACT;AACA,UAAM,OAAO;AAJJ;AAEA;AAAA,EAGX;AAAA,EALW;AAAA,EAEA;AAIb;AAEA,SAAS,UAAU,IAAsB;AACvC,SAAO,OAAO,QAAQ,OAAO,OAAO,YAAa,OAAO,OAAO,YAAY,OAAO,SAAS,EAAE;AAC/F;AAGO,SAAS,UAAU,MAAc,QAAgC;AACtE,QAAM,UAAU,aAAa,MAAM;AACnC,QAAM,QAAQ,QAAQ;AACtB,SAAO;AAAA,IACL,MAAM,iBAAiB,OAAO,IAAI,EAAE;AAAA,IACpC,aAAa,MAAM,eAAe;AAAA,IAClC,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS,EAAE,MAAM,UAAU,aAAa,6BAA6B;AAAA,QACrE,gBAAgB;AAAA,UACd,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,IACA,aAAa,EAAE,OAAO,OAAO,IAAI,IAAI,cAAc,OAAO,eAAe,MAAM;AAAA,IAC/E,MAAM,OAAgB;AACpB,UAAI,CAAC,cAAc,KAAK,KAAK,OAAO,MAAM,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK;AACpF,cAAM,IAAI,UAAU,0BAA0B,EAAE,QAAQ,IAAI,CAAC;AAC/D,UAAI,MAAM,mBAAmB,UAAa,OAAO,MAAM,mBAAmB;AACxE,cAAM,IAAI,UAAU,sCAAsC,EAAE,QAAQ,IAAI,CAAC;AAC3E,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ,OAAqD,KAAkB;AACnF,YAAM,QAAQ,QAAQ;AACtB,YAAM,MAAM,iBAAiB,IAAI,MAAM,IAAI,OAAO;AAClD,YAAM,IAAI,MAAM,MAAM,IAAI,MAAM,SAAS;AAAA,QACvC,MAAM,IAAI;AAAA,QACV,gBAAgB,MAAM,kBAAkB;AAAA,QACxC,SAAS,IAAI;AAAA,QACb,QAAQ,IAAI;AAAA,MACd,CAAC;AACD,aAAO,EAAE,MAAM,EAAE,MAAM,GAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,IAAI,CAAC,EAAG;AAAA,IAC3F;AAAA,EACF;AACF;AAEA,SAAS,WAAW,SAAqB,QAAyB;AAChE,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,MAAM;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,OAAO,QAAQ,QAAQ,CAAC;AAC9B,MAAI,IAAI,SAAS,KAAM,QAAO;AAC9B,QAAM,UAAWD,eAAc,GAAG,SAAS,wBAAiD,CAAC;AAC7F,SAAO,QAAQ;AAAA,IACb,CAAC,MACC,MAAM,UACL,EAAE,SAAS,GAAG,KAAK,IAAI,OAAO,IAAI,EAAE,QAAQ,QAAQ,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,GAAG,EAAE,KAAK,MAAM;AAAA,EACrG;AACF;AAGO,IAAM,UAAN,cAAsB,QAAQ;AAAA,EAE1B,kBAAkB,CAAC,YAAY;AAAA,EAE/B,oBAA0C;AACjD,UAAM,UAAU,KAAK,UAAU,KAAK,yBAAyB,eAAe,EAAE;AAC9E,WAAO,UAAU,QAAQ,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,MAAM,kBAAkB;AAAA,EACzE;AAAA,EAES,iBAAmC;AAC1C,YAAQ,KAAK,UAAU,KAAK,qBAAqB,yBAAyB,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;AAAA,EACjG;AAAA,EAES,0BAA0B,SAAqB,SAAS,OAAsB;AACrF,WAAO,MAAM,0BAA0B,SAAS,IAAI;AAAA,EACtD;AAAA;AAAA,EAGA,MAAe,gBAAgB,KAAoC;AACjE,UAAM,MAAM,MAAM,MAAM,gBAAgB,GAAG;AAC3C,UAAM,SAAU,IAAI,MAAc;AAClC,QAAI,OAAO;AAAA,MACT;AAAA,MACA,IAAI,WAAW,OAAO,IAAI,WAAW,MAAM,QAAQ,eAAe,QAAQ;AAAA,MAC1E,WAAW,UAAa,WAAW,OAAO,OAAO,MAAM,IAAI;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,SAAsD;AAC/D,UAAM,SAAS,QAAQ,OAAO,QAAQ;AACtC,QAAI,UAAU,CAAC,KAAK,UAAU,KAAK,kBAAkB,CAAC,WAAW,SAAS,MAAM,GAAG;AACjF,aAAO,IAAI,YAAY,cAAc,MAAM,QAAQ,iBAAiB,oBAAoB,GAAG;AAAA,QACzF,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA,UAAM,UAAU,QAAQ,OAAO,sBAAsB;AACrD,QAAI,WAAW,CAAE,sBAA4C,SAAS,OAAO,GAAG;AAC9E,aAAO,IAAI;AAAA,QACT,cAAc,MAAM,QAAQ,iBAAiB,qCAAqC,OAAO,EAAE;AAAA,QAC3F,EAAE,QAAQ,IAAI;AAAA,MAChB;AAAA,IACF;AACA,QAAI;AACJ,QAAI;AACF,aAAO,QAAQ;AAAA,IACjB,QAAQ;AACN,aAAO,IAAI,YAAY,cAAc,MAAM,QAAQ,aAAa,aAAa,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACjG;AACA,QAAI,SAAS,UAAc,cAAc,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,QAAS;AAC5E,aAAO,IAAI,YAAY,cAAc,MAAM,QAAQ,iBAAiB,iBAAiB,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,IACzG;AACA,UAAM,EAAE,QAAQ,MAAM,IAAI,IAAI,MAAM,KAAK,UAAU,WAAW,MAAM;AAAA,MAClE,MAAM,QAAQ;AAAA,MACd;AAAA,MACA,QAAQ,QAAQ,IAAI;AAAA,IACtB,CAAC;AACD,QAAI,QAAQ,OAAW,QAAO,IAAI,SAAS,MAAM,EAAE,OAAO,CAAC;AAC3D,WAAO,IAAI,YAAY,KAAK,EAAE,OAAO,CAAC;AAAA,EACxC;AAAA,EAEA,MAAM,MAAyB;AAC7B,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,EAAE,CAAC;AAAA,EACvE;AAAA,EAEA,MAAM,SAA4B;AAChC,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,OAAO,OAAO,EAAE,CAAC;AAAA,EACvE;AACF;;;ADlYO,IAAM,mBAAN,cAA+BE,cAAa;AAAA,EACjD,OAAgB,aAAa;AAAA,EAC7B,OAAgB,gBAAgB;AAAA,EAChC,OAAgB,cAAc;AAChC;AAGO,SAAS,6BAAgE;AAC9E,SAAO,eAAe,EAAE;AAC1B;AAGA,IAAe,gBAAf,cAAqCC,SAAQ;AAAA,EAG3C;AAAA,EAES,kBAAkB,CAACC,aAAY;AAAA;AAAA,EAGxC,IAAI,QAAe;AACjB,SAAK,WAAW,KAAK,YAAY,OAAO,KAAK,SAAS;AACtD,WAAO,KAAK;AAAA,EACd;AAAA,EAES,oBAA0C;AACjD,UAAM,UAAU,KAAK,yBAAyB,2BAA2B;AACzE,WAAO,UAAU,QAAQ,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,IAAI,MAAM,kBAAkB;AAAA,EACzE;AAAA,EAES,iBAAmC;AAC1C,QAAI,KAAK,kBAAmB,QAAO,MAAM,eAAe;AACxD,WAAO,KAAK,MAAM,qBAAqB,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;AAAA,EAC7D;AAAA;AAAA,EAGS,0BAA0B,SAAqB,SAAS,OAAsB;AACrF,WAAO,MAAM,0BAA0B,SAAS,IAAI;AAAA,EACtD;AAAA,EAEU,gBAAsB;AAC9B,QAAI,CAAC,gBAAgB,EAAG,OAAM,IAAI,SAAS,4DAA4D;AAAA,EACzG;AACF;AAEA,SAAS,YAAY,SAA8B;AACjD,QAAM,IAAI,QAAQ,YAAY,IAAI,QAAQ;AAC1C,MAAI,MAAM,KAAM,QAAO,CAAC,KAAK,QAAQ,KAAK,EAAE,SAAS,EAAE,YAAY,CAAC;AACpE,UAAQ,QAAQ,OAAO,QAAQ,KAAK,IAAI,SAAS,mBAAmB;AACtE;AAGA,SAAS,aAAa,UAAuC;AAC3D,MAAI,CAAC,MAAM,QAAQ,QAAQ,EAAG,QAAO;AACrC,WAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,UAAM,IAAI,SAAS,CAAC;AACpB,QAAI,GAAG,SAAS,OAAQ;AACxB,QAAI,OAAO,EAAE,YAAY,SAAU,QAAO,EAAE;AAC5C,QAAI,MAAM,QAAQ,EAAE,KAAK;AACvB,aAAO,EAAE,MACN,OAAO,CAAC,MAAW,GAAG,SAAS,MAAM,EACrC,IAAI,CAAC,MAAW,EAAE,IAAI,EACtB,KAAK,EAAE;AAAA,EACd;AACA,SAAO;AACT;AAOO,IAAM,gBAAN,cAA4B,cAAc;AAAA,EAC/C,MAAM,KAAK,SAAsD;AAC/D,UAAM,OAAQ,QAAQ,QAAQ,CAAC;AAC/B,UAAM,UAAU,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,aAAa,KAAK,QAAQ;AAC5F,QAAI,OAAO,YAAY,YAAY,CAAC,QAAQ,KAAK;AAC/C,YAAM,IAAI,oBAAoB,EAAE,SAAS,CAAC,yBAAyB,EAAE,CAAC;AACxE,UAAM,iBAAiB,KAAK,kBAAkB;AAC9C,QAAI,mBAAmB,QAAQ,OAAO,mBAAmB;AACvD,YAAM,IAAI,oBAAoB,EAAE,gBAAgB,CAAC,mBAAmB,EAAE,CAAC;AACzE,UAAM,QAAoB;AAC1B,UAAM,OAAO,EAAE,MAAM,QAAQ,MAAM,gBAAgB,QAAQ;AAC3D,QAAI;AACF,UAAI,YAAY,OAAO,GAAG;AACxB,cAAM,SAAS,MAAM,KAAK,MAAM,OAAO,OAAO,IAAI;AAClD,eAAO,OAAO,0BAA0B;AAAA,MAC1C;AACA,YAAM,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,IAAI;AAC1C,aAAO,IAAIC,aAAY;AAAA,QACrB,gBAAgB,EAAE,kBAAkB;AAAA,QACpC,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,OAAO,EAAE;AAAA,QACT,cAAc,EAAE;AAAA,MAClB,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,UAAI,eAAe,qBAAsB,OAAM,IAAI,SAAS,IAAI,OAAO;AACvE,UAAI,eAAe;AACjB,cAAM,IAAI,iBAAiBC,eAAc,GAAG,SAAS,QAAQ,IAAI,UAAU,MAAS;AACtF,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,GAAiC;AACzD,SAAO;AAAA,IACL,IAAI,OAAO,EAAE,EAAE;AAAA,IACf,OAAO,EAAE;AAAA,IACT,OAAO,EAAE;AAAA,IACT,UAAU,EAAE,YAAY,CAAC;AAAA,IACzB,WAAW,EAAE;AAAA,IACb,WAAW,EAAE;AAAA,EACf;AACF;AAGO,IAAM,uBAAN,cAAmC,cAAc;AAAA,EACtD,MAAM,IAAI,SAA2C;AACnD,SAAK,cAAc;AACnB,QAAI,CAAC,QAAQ,KAAK,gBAAiB,OAAM,IAAIC,kBAAiB;AAC9D,UAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,OAAO,QAAQ,MAAM,KAAK,KAAK,IAAI,CAAC,GAAG,GAAG;AAC1E,UAAM,SAAS,KAAK,IAAI,OAAO,QAAQ,MAAM,MAAM,KAAK,GAAG,CAAC;AAC5D,UAAM,KAAK,aAAa,QAAQ,OAAO,EAAE,OAAO,KAAK,WAAW,MAAM,QAAQ,KAAK,GAAG,CAAC;AACvF,UAAM,CAAC,OAAO,IAAI,IAAI,MAAM,QAAQ,IAAI;AAAA,MACtC,GAAG,MAAM;AAAA,MACT,GAAG,QAAQ,YAAY,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,IACvD,CAAC;AACD,WAAO,IAAIF,aAAY,EAAE,OAAO,SAAS,KAAK,IAAI,gBAAgB,EAAE,CAAC;AAAA,EACvE;AACF;AAGO,IAAM,yBAAN,cAAqC,cAAc;AAAA,EACxD,MAAgB,aAAa,SAAqB,IAA0B;AAC1E,SAAK,cAAc;AACnB,QAAI,CAAC,QAAQ,KAAK,gBAAiB,OAAM,IAAIE,kBAAiB;AAC9D,QAAI;AACF,aAAO,MAAM,gBAAgB,KAAK,WAAW,IAAI,QAAQ,IAAI;AAAA,IAC/D,SAAS,KAAK;AACZ,UAAI,eAAe,qBAAsB,OAAM,IAAI,SAAS,IAAI,OAAO;AACvE,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,SAAqB,QAAmD;AAChF,UAAM,OAAO,MAAM,KAAK,aAAa,SAAS,OAAO,OAAO,EAAE,CAAC;AAC/D,UAAM,OAAc,MAAM,QAAQ,QAAQ,OAAO,EAAE,cAAc,OAAO,KAAK,EAAE,EAAE,CAAC,EAAE,QAAQ,IAAI;AAChG,WAAO,IAAIF,aAAY;AAAA,MACrB,GAAG,iBAAiB,IAAI;AAAA,MACxB,UAAU,KAAK,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,SAAS,EAAE,SAAS,WAAW,EAAE,UAAU,EAAE;AAAA,IACpG,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAAO,SAAqB,QAAmD;AACnF,UAAM,OAAO,MAAM,KAAK,aAAa,SAAS,OAAO,OAAO,EAAE,CAAC;AAC/D,UAAM,KAAK,OAAO;AAClB,WAAO,IAAIA,aAAY,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9C;AACF;AAiBO,IAAM,cAAN,MAAkB;AAAA,EACd,WAAW,oBAAI,IAAwB;AAAA,EACvC;AAAA,EACT;AAAA,EAEA,YAAY,OAA2B,CAAC,GAAG;AACzC,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,SAAS,MAAc,YAA8B;AACnD,QAAI,CAAC,mBAAmB,KAAK,IAAI;AAC/B,YAAM,IAAIG,sBAAqB,eAAe,IAAI,kDAAkD;AACtG,QAAI,KAAK,SAAS,IAAI,IAAI;AACxB,YAAM,IAAIA,sBAAqB,mBAAmB,IAAI,0BAA0B;AAClF,SAAK,SAAS,IAAI,MAAM,UAAU;AAClC,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,QAAQ,KAAiB;AACpC,WAAO,kBAAkB,OAAO,CAAC,SAAS,KAAK,OAAO,IAAI,CAAC;AAAA,EAC7D;AAAA;AAAA,EAGA,OAAO,MAAqB;AAC1B,UAAM,MAAM,KAAK,SAAS,IAAI,IAAI;AAClC,QAAI,CAAC,IAAK,OAAM,IAAIA,sBAAqB,2BAA2B,IAAI,IAAI;AAC5E,UAAM,QAAQ,IAAI,IAAI;AACtB,UAAM,YAAY;AAClB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,QAAkB;AACpB,WAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,EACjC;AAAA,EAEA,UAAuB;AACrB,UAAM,SAAS,KAAK,KAAK,iBAAiB;AAC1C,UAAM,MAAmB,CAAC;AAC1B,eAAW,QAAQ,KAAK,SAAS,KAAK,GAAG;AACvC,YAAM,OAAO,EAAE,aAAa,MAAM,WAAW,KAAK;AAClD,YAAM,OAAO,cAAc,OAAO,IAAI;AACtC,UAAI;AAAA,QACFC,MAAK,GAAG,IAAI,UAAU,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,IAAI,QAAQ,CAAC;AAAA,QAC9DA,MAAK,GAAG,IAAI,SAAS,IAAI;AAAA,QACzBA,MAAK,GAAG,IAAI,mBAAmB,qBAAqB,OAAO,IAAI,GAAG;AAAA,UAChE,MAAM,GAAG,MAAM,IAAI,IAAI;AAAA,QACzB,CAAC;AAAA,QACDA,MAAK,GAAG,IAAI,6BAA6B,uBAAuB,OAAO,IAAI,GAAG;AAAA,UAC5E,MAAM,GAAG,MAAM,IAAI,IAAI;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAA2E,CAAC,GAAgB;AAC9F,WAAO,KAAK,UAAU,IAAI,EAAE;AAAA,EAC9B;AAAA;AAAA,EAGA,UAAU,OAA2E,CAAC,GAAc;AAClG,UAAM,EAAE,SAAS,MAAM,GAAG,KAAK,IAAI;AACnC,UAAM,QAAQ,WAAW,OAAO,KAAK,QAAQ,WAAW,QAAQ,CAAC,IAAI;AACrE,UAAM,YAAyC,CAAC;AAChD,eAAW,QAAQ,MAAO,WAAU,IAAI,IAAI,MAAM,KAAK,OAAO,IAAI;AAClE,WAAO,IAAI,UAAU,EAAE,GAAG,MAAM,QAAQ,UAAU,CAAC;AAAA,EACrD;AAAA;AAAA,EAGA,IAAI,OAAoB;AACtB,SAAK,UAAU,KAAK,QAAQ;AAC5B,WAAO,KAAK;AAAA,EACd;AACF;;;AE/RA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACK;;;ACTP,SAAS,wBAAAC,6BAA4B;AACrC,SAAS,oBAAoB,oBAAoB;AAMjD,IAAM,iBAAyC;AAAA,EAC7C,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,kBAAkB;AACpB;AAEA,IAAM,WAAW,oBAAI,IAAI,CAAC,QAAQ,UAAU,YAAY,UAAU,iBAAiB,SAAS,CAAC;AAsB7F,SAAS,cAAc,SAAsB;AAC3C,MAAI;AACJ,MAAI;AACF,UAAM,OAAO,IAAI,QAAQ;AACzB,YAAQ,KAAK,UAAU,SAAS,QAAQ,UAAU;AAAA,EACpD,QAAQ;AACN,YAAQ;AAAA,EACV;AACA,MAAI,OAAO;AACT,WAAO,iBAAiB,OAAO,MAAM,MAAM,iBAAiB,EAAE,QAAQ,QAAQ,GAAG,EAAE,YAAY,CAAC;AAClG,SAAO,iBAAiB,UAAU,OAAO,QAAQ,IAAI,EAAE,QAAQ,kBAAkB,EAAE,CAAC,CAAC;AACvF;AAYO,IAAM,eAAN,cAA2B,QAAQ;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACC;AAAA,EAEV,YAAY,QAAa,OAA4B,CAAC,GAAG;AACvD,UAAM;AACN,SAAK,OAAO;AACZ,QAAI,kBAAkB,oBAAoB;AACxC,WAAK,QAAQ;AACb,WAAK,SAAS,iBAAiB,KAAK,WAAW,OAAO,OAAO,QAAQ,OAAO,GAAG,KAAK,OAAO,SAAS;AAAA,IACtG,WAAW,OAAO,WAAW,YAAY;AACvC,WAAK,SAAS,iBAAiB,KAAK,UAAU,cAAc,MAAM,CAAC;AACnE,YAAM,SAAS,IAAI,aAAa;AAChC,WAAK,QAAQ,OAAO,SAAS,KAAK,QAAQ,QAAQ,KAAK,WAAW,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC,CAAC;AAAA,IACpG,OAAO;AACL,YAAM,IAAI,UAAU,kEAAkE;AAAA,IACxF;AAAA,EACF;AAAA;AAAA,EAGA,cAAgC;AAC9B,QAAI,KAAK,MAAO,QAAO,KAAK;AAC5B,UAAM,YAAY,KAAK,MAAM;AAC7B,UAAM,SAAS,KAAK,KAAK,WAAW;AACpC,SAAK,QAAQ,OAAO,IAAI,CAAC,SAAS;AAChC,YAAM,SAAS,eAAe,IAAI,KAAK;AACvC,UAAI,CAAC,UAAU,SAAS,MAAM,GAAG;AAC/B,cAAM,IAAIC;AAAA,UACR,GAAG,KAAK,MAAM,QAAQ,IAAI,0BAA0B,IAAI,iBAAiB,UAAU,KAAK,IAAI,CAAC;AAAA,QAC/F;AAAA,MACF;AACA,aAAO,EAAE,QAAQ,QAAQ,UAAU,IAAI,GAAG,aAAa,KAAK,KAAK,eAAe,IAAI,EAAE;AAAA,IACxF,CAAC;AACD,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAwB;AACtB,WAAO,KAAK,YAAY,EAAE,IAAI,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC;AAAA,EAC9D;AAAA,EAEA,IAAI,QAAa;AACf,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEU,aAA4C;AACpD,UAAM,OAAO,KAAK,OAAO;AACzB,WAAO;AAAA,MACL,KAAK,OAAO,OAAO,KAAK,WAAW,IAAI,KAAK,MAAM;AAAA,MAClD,MAAM,OAAO,OAAO,KAAK,iBAAiB,IAAI,KAAK;AAAA,IACrD;AAAA,EACF;AAAA,EAEU,SAA+D;AACvE,UAAM,OAAO,KAAK,MAAM,QAAQ,UAAU;AAC1C,UAAM,QAAQ,KAAK,eAAe;AAClC,UAAM,QAAQ,KAAK,kBAAkB;AACrC,UAAM,QAAQ,UAAU,OAAO,OAAO;AACtC,QAAI,SAAqB,EAAE,MAAM,CAAC,WAAW,QAAQ,EAAE;AACvD,UAAM,OAAO,KAAK,OAAO;AACzB,UAAM,aAAa,SAAS,UAAU,OAAO,KAAK,KAAK,KAAK,kBAAkB,KAAK;AACnF,QAAI,cAAc,OAAO,WAAW,eAAe,YAAY;AAC7D,UAAI;AACF,cAAM,IAAI,WAAW,WAAW;AAChC,iBAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,WAAW,QAAQ,GAAG,GAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAG;AAAA,MAC9F,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAM,EAAE,IAAI,IAAI,KAAK,WAAW;AAChC,WAAO,EAAE,OAAO,OAAO,QAAQ,EAAE,GAAG,QAAQ,aAAa,eAAe,KAAK,YAAY,GAAG,IAAI,EAAE;AAAA,EACpG;AAAA,EAEU,SACR,MACA,UACA;AACA,QAAI,KAAK,YAAa,QAAO,KAAK;AAClC,UAAM,EAAE,KAAK,KAAK,IAAI,KAAK,WAAW;AACtC,YAAQ,KAAK,QAAQ;AAAA,MACnB,KAAK;AACH,eAAO,QAAQ,IAAI,kGAAkG,IAAI;AAAA,MAC3H,KAAK;AACH,eAAO,WAAW,GAAG;AAAA,MACvB,KAAK;AACH,eAAO,YAAY,GAAG,yBAAyB,GAAG;AAAA,MACpD,KAAK;AACH,eAAO,aAAa,GAAG,wDAAwD,GAAG;AAAA,MACpF,KAAK;AACH,eAAO,2BAA2B,GAAG,4DAA4D,GAAG;AAAA,MACtG,KAAK;AACH,eAAO,YAAY,GAAG;AAAA,IAC1B;AACA,UAAM,QAAQ,KAAK,MAAM,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,MAAM;AACxE,UAAM,OAAO,SAAS,eAAgB,OAAO,OAAO;AACpD,QAAI,KAAM,QAAO;AACjB,WAAO,SAAS,SACZ,YAAY,KAAK,MAAM,mBAAmB,GAAG,MAC7C,YAAY,KAAK,MAAM,eAAe,IAAI;AAAA,EAChD;AAAA,EAEU,UAAU,MAAiC;AACnD,UAAM,YAAY,KAAK,MAAM,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,MAAM;AAC7E,UAAM,WAAW,UAAU,CAAC;AAC5B,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC3D,UAAM,QAAQ,CAAC,SAAS,IAAI,KAAK,MAAM;AACvC,UAAM,aAAyC,CAAC;AAChD,UAAM,WAAqB,CAAC;AAC5B,UAAM,SAAS,SAAS,SAAS,KAAK,OAAO,IAAI;AACjD,QAAI,QAAQ;AACV,iBAAW,OAAO,KAAK,IAAI,OAAO;AAClC,eAAS,KAAK,OAAO,KAAK;AAAA,IAC5B;AACA,UAAM,gBAAgB,QAAQ,KAAK,CAAC,MAAM,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,CAAC,CAAC;AAC9E,QAAI,WAAqB,CAAC;AAC1B,QAAI,WAAW;AACf,QAAI,YAAsB,CAAC;AAC3B,QAAI,YAAY;AAEhB,QAAI,eAAe;AACjB,YAAM,SAAS,KAAK,MAAM,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,MAAM,GAAG,UAAU,CAAC;AACvF,YAAM,gBAAgB,CAAC,SAAS,OAAO;AACvC,YAAM,SAAS,gBACX,KAAK,MAAM,WAAW,KAAK,QAAQ,EAAE,MAAM,SAAS,SAAS,KAAK,WAAW,gBAAgB,CAAC,IAC9F;AACJ,UAAI,QAAQ;AACV,cAAM,OAAO,iBAAiB,MAAM;AACpC,cAAM,QAAQ,KAAK;AACnB,mBAAW,CAAC,CAAC,UAAU,OAAO,SAAS;AACvC,YAAI,UAAU;AACZ,qBAAW,OAAO,EAAE,GAAG,MAAM,aAAa,gBAAgB;AAC1D,cAAK,KAAK,UAAmC,OAAQ,UAAS,KAAK,MAAM;AAAA,QAC3E,OAAO;AACL,iBAAO,OAAO,YAAY,KAAK;AAC/B,qBAAW,KAAM,KAAK,YAAqC,CAAC,EAAG,UAAS,KAAK,CAAC;AAC9E,qBAAW,OAAO,KAAK,KAAK;AAAA,QAC9B;AAAA,MACF,OAAO;AACL,mBAAW;AACX,mBAAW,OAAO;AAAA,UAChB,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,QAAI,KAAK,WAAW,QAAQ;AAC1B,YAAM,SAAS,KAAK,eAAe;AACnC,YAAM,EAAE,YAAY,IAAI,UAAU,GAAG,IAAI,uBAAuB,MAAM;AACtE,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,EAAE,EAAG,KAAI,EAAE,KAAK,YAAa,YAAW,CAAC,IAAI;AACjF,eAAS,KAAK,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC;AACxD,kBAAY,OAAO,KAAK,EAAE;AAAA,IAC5B,WAAW,QAAQ,SAAS,KAAK,KAAK,OAAO;AAC3C,kBAAY;AACZ,iBAAW,QAAQ,EAAE,MAAM,UAAU,aAAa,oCAAoC;AAAA,IACxF;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,iBAAW,SAAS,EAAE,MAAM,UAAU,MAAM,SAAS,aAAa,6BAA6B;AAAA,IACjG;AAEA,UAAM,cAA0B,EAAE,MAAM,UAAU,WAAW;AAC7D,QAAI,SAAS,OAAQ,aAAY,WAAW;AAC5C,UAAM,cAA+B;AAAA,MACnC,OAAO,GAAG,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,MACxD,cAAc,QAAQ,MAAM,CAAC,MAAM,MAAM,SAAS,MAAM,MAAM;AAAA,MAC9D,iBAAiB,KAAK,WAAW,aAAa,QAAQ,SAAS,QAAQ;AAAA,MACvE,gBAAgB,QAAQ,MAAM,CAAC,MAAM,CAAC,OAAO,QAAQ,OAAO,QAAQ,EAAE,SAAS,CAAC,CAAC;AAAA,MACjF,eAAe;AAAA,IACjB;AACA,UAAM,QAAQ,KAAK;AACnB,WAAO;AAAA,MACL,MAAM,iBAAiB,GAAG,KAAK,MAAM,IAAI,KAAK,MAAM,EAAE;AAAA,MACtD,aAAa,KAAK,SAAS,MAAM,QAAQ;AAAA,MACzC;AAAA,MACA;AAAA,MACA,OAAO,CAAC,UAAmB;AACzB,YAAI,UAAU,UAAa,UAAU,KAAM,QAAO,CAAC;AACnD,YAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK;AAClD,gBAAM,IAAI,UAAU,8BAA8B;AACpD,cAAM,UAAU,SAAS,OAAO,CAAC,MAAO,MAAc,CAAC,MAAM,MAAS;AACtE,YAAI,UAAU,QAAQ,SAAS,OAAO,KAAK;AACzC,gBAAM,IAAI,UAAU,8BAA8B,OAAO,KAAK,MAAM,EAAE,QAAQ,IAAI,CAAC;AACrF,eAAO;AAAA,MACT;AAAA,MACA,SAAS,OAAO,OAA4B,QAAqB;AAC/D,cAAM,OAAO,EAAE,GAAI,SAAS,CAAC,EAAG;AAChC,cAAM,SAAkC,CAAC;AACzC,YAAI,QAAQ;AACV,iBAAO,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK;AACxC,iBAAO,KAAK,OAAO,KAAK;AAAA,QAC1B;AACA,cAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,OAAO,YAAY,IAAI;AAC7E,eAAO,KAAK;AACZ,YAAI;AACJ,YAAI;AACJ,YAAI,KAAK,WAAW,QAAQ;AAC1B,kBAAQ,CAAC;AACT,qBAAW,KAAK,UAAW,KAAI,KAAK,CAAC,MAAM,UAAa,KAAK,CAAC,MAAM,KAAM,OAAM,CAAC,IAAI,KAAK,CAAC;AAAA,QAC7F,WAAW,aAAa,KAAK,SAAS,OAAO,KAAK,UAAU,UAAU;AACpE,kBAAQ,KAAK;AACb,iBAAO,KAAK;AAAA,QACd;AACA,YAAI,iBAAiB,WAAW,OAAO;AACrC,cAAI,SAAU,QAAO,KAAK,QAAQ,CAAC;AAAA,eAC9B;AACH,mBAAO,CAAC;AACR,uBAAW,KAAK,SAAU,KAAI,KAAK,KAAM,CAAC,KAAa,CAAC,IAAI,KAAK,CAAC;AAAA,UACpE;AAAA,QACF;AAEA,cAAM,OAAO,IAAI,MAAM,kBAAkB,IAAI,OAAO;AACpD,cAAM,MAAM,MAAM,MAAM,OAAO,KAAK,QAAQ,EAAE,MAAM,QAAQ,OAAO,MAAM,OAAO,CAAC;AACjF,eAAO,WAAW,IAAI,QAAQ,IAAI,IAAI;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGU,iBAAiD;AACzD,UAAM,OAAO,KAAK,MAAM,QAAQ,MAAM;AACtC,UAAM,MAAsC,CAAC;AAC7C,UAAM,WACJ,OAAO,KAAK,sBAAsB,aAAa,KAAK,kBAAkB,IAAK,KAAK,kBAAkB,CAAC;AACrG,eAAW,KAAK,UAAU;AACxB,YAAM,IAAI,IAAI,EAAE;AAChB,UAAI,OAAO,EAAE,iCAAiC;AAC5C,YAAI,KAAK,GAAG,EAAE,6BAA6B,IAAI,CAAC;AAAA,IACpD;AACA,UAAM,YAAY,KAAK;AACvB,QAAI,aAAa,OAAO,UAAU,iCAAiC;AACjE,UAAI,KAAK,GAAG,UAAU,6BAA6B,IAAI,CAAC;AAC1D,UAAM,OAAO,oBAAI,IAAY;AAC7B,WAAO,IAAI,OAAO,CAAC,MAAM;AACvB,YAAM,OAAO,OAAO,EAAE,IAAI;AAC1B,UAAI,KAAK,IAAI,IAAI,EAAG,QAAO;AAC3B,WAAK,IAAI,IAAI;AACb,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAGO,SAAS,WAAW,QAAgB,MAAwB;AACjE,MAAI,UAAU,IAAK,OAAM,IAAI,UAAU,aAAa,QAAQ,IAAI,GAAG,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAC3F,MAAI,WAAW,OAAO,SAAS,QAAQ,SAAS,GAAI,QAAO,EAAE,SAAS,MAAM,OAAO;AACnF,SAAO;AACT;AAEA,SAAS,aAAa,QAAgB,MAAuB;AAC3D,QAAM,SACJ,QAAQ,OAAO,SAAS,YAAY,OAAQ,KAAa,WAAW,WAC/D,KAAa,SACd,OAAO,SAAS,YAAY,OAC1B,OACA,WAAW,MACT,sBAAsB,KAAK,UAAU,IAAI,CAAC,KAC1C;AACV,SAAO,GAAG,UAAU,iBAAiB,UAAU,MAAM;AACvD;;;AD5SA,IAAM,UAA2C;AAAA,EAC/C,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAkCA,SAAS,kBAAkB,OAAiB;AAC1C,QAAM,MAAM,cAAc,gBAAgB;AAAA,IACxC,OAAgB,OAAO,EAAE,OAAO,QAAQ,UAAmB;AAAA,EAC7D;AACA,SAAO,eAAe,KAAK,QAAQ,EAAE,OAAO,GAAG,MAAM,MAAM,UAAU,aAAa,CAAC;AACnF,SAAO;AACT;AAGA,SAAS,aAAa,OAAY,MAA8B;AAC9D,QAAM,aAAa,KAAK,cAAc,kBAAkB,KAAK;AAC7D,QAAM,WAAkB,CAAC;AACzB,MAAI,KAAK,aAAc,UAAS,KAAK,WAAW;AAChD,MAAI,KAAK,cAAc,OAAQ,UAAS,KAAK,YAAY;AACzD,MAAI,KAAK,kBAAkB,KAAK,SAAU,UAAS,KAAK,cAAc;AACtE,QAAM,WAAW,KAAK,YAAY;AAClC,QAAM,cAAc,KAAK,eAAe,KAAK,IAAI,KAAK,QAAQ;AAC9D,QAAM,YAAY,MAAM,wBAAwB,qBAAqB;AAAA,IAC1D,WAAW;AAAA,IACX,qBAAqB;AAAA,IACrB,cAAc;AAAA,EACzB;AACA,QAAM,UAAU,cAAc,aAAa;AAAA,IAChC,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,eAAe,KAAK;AAAA,IACpB,iBAAiB,KAAK;AAAA,IACtB,WAAW,KAAK;AAAA,IAChB,kBAAkB,KAAK;AAAA,IAEhC,cAAc;AACZ,YAAM;AACN,UAAI,KAAK,kBAAmB,MAAK,oBAAoB,KAAK;AAAA,IAC5D;AAAA,IAES,cAAmB;AAC1B,YAAM,KAAK,MAAM,YAAY;AAC7B,aAAO,KAAK,SAAS,KAAK,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI;AAAA,IAC5D;AAAA,IAEA,MAAe,cAAcC,aAAgC;AAC3D,YAAMA,YAAW,KAAK,KAAK,aAAa,MAAM,KAAK,WAAW,KAAK,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAAC;AAAA,IACjG;AAAA,IAEA,MAAe,cAAcA,aAAgC;AAC3D,YAAMA,YAAW,KAAK,KAAK,aAAa,MAAM,KAAK,WAAW,KAAK,QAAQ,MAAM,QAAQ,IAAI,CAAC,CAAC;AAAA,IACjG;AAAA,EACF;AACA,SAAO,eAAe,SAAS,QAAQ,EAAE,OAAO,GAAG,MAAM,MAAM,UAAU,eAAe,CAAC;AACzF,SAAO;AACT;AAgBO,IAAM,aAAN,cAAyB,aAAa;AAAA,EAClC;AAAA,EACA;AAAA,EAET,YAAY,OAAY,OAA0B,CAAC,GAAG;AACpD,QAAI,CAAC,OAAO,MAAO,OAAM,IAAI,UAAU,mCAAmC;AAC1E,UAAM,SACJ,KAAK,UACL,iBAAiB,OAAO,MAAM,MAAM,iBAAiB,EAAE,QAAQ,QAAQ,GAAG,EAAE,YAAY,CAAC;AAC3F,UAAM,aAAa,OAAO,IAAI,GAAG,EAAE,QAAQ,UAAU,MAAM,MAAM,UAAU,CAAC;AAC5E,SAAK,aAAa;AAClB,SAAK,eAAe;AAAA,EACtB;AAAA,EAES,cAAgC;AACvC,QAAI,CAAC,KAAK,OAAO;AACf,YAAM,UAAU,KAAK,aAAa,WAAW,CAAC,QAAQ,UAAU;AAChE,WAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM;AAC9B,cAAM,SAAS,QAAQ,CAAC;AACxB,YAAI,CAAC;AACH,gBAAM,IAAI,UAAU,+BAA+B,CAAC,UAAU,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC,IAAI;AACnG,eAAO,EAAE,QAAQ,QAAQ,GAAG,aAAa,KAAK,aAAa,eAAe,CAAC,EAAE;AAAA,MAC/E,CAAC;AAAA,IACH;AACA,WAAO,KAAK;AAAA,EACd;AACF;;;AEvIA,SAAS,QAAQ,OAA2B,MAAgE;AAC1G,MAAI,OAAO,SAAS,WAAY,QAAO,KAAK,KAAK;AACjD,SAAO,KAAK,SAAS,MAAM,MAAM,KAAK,KAAK,SAAS,MAAM,QAAQ;AACpE;AASO,IAAM,cAAN,cAA0B,QAAQ;AAAA,EACvC,YACW,QACA,OAA2B,CAAC,GACrC;AACA,UAAM;AAHG;AACA;AAAA,EAGX;AAAA,EAJW;AAAA,EACA;AAAA;AAAA,EAMX,WAA2B;AACzB,UAAM,MAAsB,CAAC;AAC7B,eAAW,SAAS,KAAK,OAAO,UAAU;AACxC,UAAI,KAAK,KAAK,WAAW,CAAC,QAAQ,OAAO,KAAK,KAAK,OAAO,EAAG;AAC7D,UAAI,KAAK,KAAK,WAAW,QAAQ,OAAO,KAAK,KAAK,OAAO,EAAG;AAC5D,UAAI,UAAU,KAAK,KAAK,UAAU,MAAM,MAAM,KAAK,KAAK,KAAK,UAAU,MAAM,QAAQ;AACrF,UAAI,KAAK,KAAK,UAAU;AACtB,cAAM,OAAO,IAAI,IAAI,MAAM,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAC3F,mBAAW,WAAW,MAAM,SAAS,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAAA,MAChE;AACA,UAAI,WAAW,CAAC,QAAQ,OAAQ;AAChC,UAAI,KAAK,IAAI,aAAa,OAAO,UAAU,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,WAAwB;AACtB,UAAM,WAAW,MAAM,QAAQ,KAAK,KAAK,OAAO,IAAI,IAAI,IAAI,KAAK,KAAK,OAAO,IAAI;AACjF,WAAO,KAAK,SAAS,EAClB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAC3B,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,EACzC;AACF;","names":["anonymousUser","ImproperlyConfigured","tryGetContext","apps","apps","tryGetContext","tryGetContext","tryGetContext","apps","tryGetContext","tryGetContext","apps","tryGetContext","tryGetContext","tool","ImproperlyConfigured","ImproperlyConfigured","ImproperlyConfigured","tryGetContext","anonymousUser","tryGetContext","Migration","tryGetContext","Migration","ImproperlyConfigured","path","tryGetContext","APIException","APIResponse","APIView","JSONRenderer","NotAuthenticated","ImproperlyConfigured","tryGetContext","ImproperlyConfigured","tool","id","tryGetContext","r","APIException","APIView","JSONRenderer","APIResponse","tryGetContext","NotAuthenticated","ImproperlyConfigured","path","ImproperlyConfigured","ImproperlyConfigured","serializer"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,100 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghuri/agents",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Ghuri agents: AI agents with tools generated from models and viewsets, plus MCP",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Ghuri contributors",
|
|
8
|
+
"homepage": "https://github.com/ghurijs/agents#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/ghurijs/agents.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/ghurijs/agents/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ghuri",
|
|
18
|
+
"django",
|
|
19
|
+
"cloudflare",
|
|
20
|
+
"workers",
|
|
21
|
+
"hono",
|
|
22
|
+
"drizzle",
|
|
23
|
+
"d1",
|
|
24
|
+
"r2",
|
|
25
|
+
"framework"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"main": "./dist/index.js",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE"
|
|
39
|
+
],
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup",
|
|
45
|
+
"dev": "tsup --watch",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"lint": "biome check src test",
|
|
50
|
+
"format": "biome format --write src test"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@ai-sdk/anthropic": "^4.0.0",
|
|
54
|
+
"@ai-sdk/openai": "^4.0.0",
|
|
55
|
+
"@ghuri/core": "^0.1.0-alpha.0",
|
|
56
|
+
"@ghuri/orm": "^0.1.0-alpha.0",
|
|
57
|
+
"@ghuri/rest": "^0.1.0-alpha.0",
|
|
58
|
+
"ai": "^7.0.0",
|
|
59
|
+
"hono": "^4.13.0",
|
|
60
|
+
"workers-ai-provider": "^4.0.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@ai-sdk/anthropic": "^4.0.0",
|
|
64
|
+
"@ai-sdk/openai": "^4.0.0",
|
|
65
|
+
"@biomejs/biome": "^2.6.6",
|
|
66
|
+
"@electric-sql/pglite": "^0.5.16",
|
|
67
|
+
"@ghuri/auth": "^0.1.0-alpha.0",
|
|
68
|
+
"@ghuri/core": "^0.1.0-alpha.0",
|
|
69
|
+
"@ghuri/orm": "^0.1.0-alpha.0",
|
|
70
|
+
"@ghuri/rest": "^0.1.0-alpha.0",
|
|
71
|
+
"@types/node": "^24.0.0",
|
|
72
|
+
"ai": "^7.0.0",
|
|
73
|
+
"better-sqlite3": "^13.1.1",
|
|
74
|
+
"drizzle-orm": "^0.45.4",
|
|
75
|
+
"esbuild": "^0.27.7",
|
|
76
|
+
"hono": "^4.13.0",
|
|
77
|
+
"tsup": "^8.5.1",
|
|
78
|
+
"typescript": "~5.9.3",
|
|
79
|
+
"vitest": "^5.1.0",
|
|
80
|
+
"workers-ai-provider": "^4.0.1"
|
|
81
|
+
},
|
|
82
|
+
"publishConfig": {
|
|
83
|
+
"access": "public",
|
|
84
|
+
"tag": "next"
|
|
85
|
+
},
|
|
86
|
+
"dependencies": {
|
|
87
|
+
"zod": "^4.1.0"
|
|
88
|
+
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"workers-ai-provider": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"@ai-sdk/anthropic": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"@ai-sdk/openai": {
|
|
97
|
+
"optional": true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|