@d4y/agent-runtime-nuxt 0.1.0

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.
Files changed (57) hide show
  1. package/README.md +314 -0
  2. package/dist/module.d.mts +69 -0
  3. package/dist/module.json +12 -0
  4. package/dist/module.mjs +60 -0
  5. package/dist/runtime/components/AgentRuntimeArtifactPreview.d.vue.ts +14 -0
  6. package/dist/runtime/components/AgentRuntimeArtifactPreview.vue +112 -0
  7. package/dist/runtime/components/AgentRuntimeArtifactPreview.vue.d.ts +14 -0
  8. package/dist/runtime/composables/useAgentRuntime.d.ts +130 -0
  9. package/dist/runtime/composables/useAgentRuntime.js +306 -0
  10. package/dist/runtime/composables/useAgentRuntimeMarkdown.d.ts +15 -0
  11. package/dist/runtime/composables/useAgentRuntimeMarkdown.js +109 -0
  12. package/dist/runtime/server/api/app.get.d.ts +6 -0
  13. package/dist/runtime/server/api/app.get.js +26 -0
  14. package/dist/runtime/server/api/conversations/[id]/abort.post.d.ts +6 -0
  15. package/dist/runtime/server/api/conversations/[id]/abort.post.js +18 -0
  16. package/dist/runtime/server/api/conversations/[id]/env.post.d.ts +10 -0
  17. package/dist/runtime/server/api/conversations/[id]/env.post.js +22 -0
  18. package/dist/runtime/server/api/conversations/[id]/files/raw/[...path].get.d.ts +11 -0
  19. package/dist/runtime/server/api/conversations/[id]/files/raw/[...path].get.js +31 -0
  20. package/dist/runtime/server/api/conversations/[id]/files.get.d.ts +14 -0
  21. package/dist/runtime/server/api/conversations/[id]/files.get.js +16 -0
  22. package/dist/runtime/server/api/conversations/[id]/history.get.d.ts +2 -0
  23. package/dist/runtime/server/api/conversations/[id]/history.get.js +16 -0
  24. package/dist/runtime/server/api/conversations/[id]/messages.post.d.ts +7 -0
  25. package/dist/runtime/server/api/conversations/[id]/messages.post.js +20 -0
  26. package/dist/runtime/server/api/conversations/[id]/stream.get.d.ts +9 -0
  27. package/dist/runtime/server/api/conversations/[id]/stream.get.js +28 -0
  28. package/dist/runtime/server/api/conversations/[id].delete.d.ts +2 -0
  29. package/dist/runtime/server/api/conversations/[id].delete.js +18 -0
  30. package/dist/runtime/server/api/conversations.post.d.ts +7 -0
  31. package/dist/runtime/server/api/conversations.post.js +17 -0
  32. package/dist/runtime/server/utils/agent-runtime.d.ts +12 -0
  33. package/dist/runtime/server/utils/agent-runtime.js +12 -0
  34. package/dist/runtime/utils/files.d.ts +16 -0
  35. package/dist/runtime/utils/files.js +42 -0
  36. package/dist/types.d.mts +9 -0
  37. package/package.json +67 -0
  38. package/src/frontend.ts +16 -0
  39. package/src/module.ts +155 -0
  40. package/src/nitro-globals.d.ts +8 -0
  41. package/src/runtime/components/AgentRuntimeArtifactPreview.vue +192 -0
  42. package/src/runtime/composables/useAgentRuntime.ts +527 -0
  43. package/src/runtime/composables/useAgentRuntimeMarkdown.ts +145 -0
  44. package/src/runtime/server/api/app.get.ts +50 -0
  45. package/src/runtime/server/api/conversations/[id]/abort.post.ts +26 -0
  46. package/src/runtime/server/api/conversations/[id]/env.post.ts +34 -0
  47. package/src/runtime/server/api/conversations/[id]/files/raw/[...path].get.ts +48 -0
  48. package/src/runtime/server/api/conversations/[id]/files.get.ts +33 -0
  49. package/src/runtime/server/api/conversations/[id]/history.get.ts +20 -0
  50. package/src/runtime/server/api/conversations/[id]/messages.post.ts +29 -0
  51. package/src/runtime/server/api/conversations/[id]/stream.get.ts +41 -0
  52. package/src/runtime/server/api/conversations/[id].delete.ts +22 -0
  53. package/src/runtime/server/api/conversations.post.ts +26 -0
  54. package/src/runtime/server/utils/agent-runtime.ts +33 -0
  55. package/src/runtime/utils/files.ts +78 -0
  56. package/src/shared.ts +46 -0
  57. package/src/vue-shim.d.ts +6 -0
@@ -0,0 +1,31 @@
1
+ import { Readable } from "node:stream";
2
+ import { agentRuntime } from "../../../../../utils/agent-runtime.js";
3
+ const PASS_THROUGH_HEADERS = ["content-type", "content-length", "content-disposition", "cache-control"];
4
+ export default defineEventHandler(async (event) => {
5
+ const cfg = agentRuntime();
6
+ const id = getRouterParam(event, "id");
7
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
8
+ const apiPrefix = (useRuntimeConfig().public.agentRuntime?.apiPrefix ?? "/api/agent-runtime").replace(/\/+$/, "");
9
+ const marker = `${apiPrefix}/conversations/${id}/files/raw/`;
10
+ const idx = event.path.indexOf(marker);
11
+ const tail = idx >= 0 ? event.path.slice(idx + marker.length) : "";
12
+ if (!tail) throw createError({ statusCode: 400, statusMessage: "missing file path" });
13
+ const upstreamUrl = `${cfg.baseUrl}/v1/conversations/${id}/files/raw/${tail}`;
14
+ const controller = new AbortController();
15
+ event.node.req.on("close", () => controller.abort());
16
+ const upstream = await fetch(upstreamUrl, {
17
+ headers: { "X-Agent-Runtime-App-Key": cfg.appKey },
18
+ signal: controller.signal
19
+ });
20
+ if (!upstream.ok || !upstream.body) {
21
+ throw createError({
22
+ statusCode: upstream.status || 502,
23
+ statusMessage: `agent-runtime file fetch failed: ${upstream.status} ${upstream.statusText}`
24
+ });
25
+ }
26
+ for (const name of PASS_THROUGH_HEADERS) {
27
+ const v = upstream.headers.get(name);
28
+ if (v) setHeader(event, name, v);
29
+ }
30
+ return sendStream(event, Readable.fromWeb(upstream.body));
31
+ });
@@ -0,0 +1,14 @@
1
+ /** Single file entry as returned by agent-runtime. */
2
+ export interface FileEntry {
3
+ name: string;
4
+ relPath: string;
5
+ size: number;
6
+ mtime: string;
7
+ mimeType: string;
8
+ }
9
+ /**
10
+ * GET `${apiPrefix}/conversations/:id/files` — lists the workspace files
11
+ * the agent has produced (or read in) so the UI can show a side panel.
12
+ */
13
+ declare const _default: any;
14
+ export default _default;
@@ -0,0 +1,16 @@
1
+ import { agentRuntime } from "../../../utils/agent-runtime.js";
2
+ export default defineEventHandler(async (event) => {
3
+ const cfg = agentRuntime();
4
+ const id = getRouterParam(event, "id");
5
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
6
+ const response = await fetch(`${cfg.baseUrl}/v1/conversations/${id}/files`, {
7
+ headers: { "X-Agent-Runtime-App-Key": cfg.appKey }
8
+ });
9
+ if (!response.ok) {
10
+ throw createError({
11
+ statusCode: response.status,
12
+ statusMessage: await response.text()
13
+ });
14
+ }
15
+ return await response.json();
16
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,16 @@
1
+ import { agentRuntime } from "../../../utils/agent-runtime.js";
2
+ export default defineEventHandler(async (event) => {
3
+ const cfg = agentRuntime();
4
+ const id = getRouterParam(event, "id");
5
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
6
+ const response = await fetch(`${cfg.baseUrl}/v1/conversations/${id}/history`, {
7
+ headers: { "X-Agent-Runtime-App-Key": cfg.appKey }
8
+ });
9
+ if (!response.ok) {
10
+ throw createError({
11
+ statusCode: response.status,
12
+ statusMessage: await response.text()
13
+ });
14
+ }
15
+ return await response.json();
16
+ });
@@ -0,0 +1,7 @@
1
+ /**
2
+ * POST `${apiPrefix}/conversations/:id/messages` — append a user turn.
3
+ * The optional `context` field is forwarded verbatim to agent-runtime, where
4
+ * the agent picks it up as per-turn dynamic context.
5
+ */
6
+ declare const _default: any;
7
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import { agentRuntime, agentRuntimeHeaders } from "../../../utils/agent-runtime.js";
2
+ export default defineEventHandler(async (event) => {
3
+ const cfg = agentRuntime();
4
+ const id = getRouterParam(event, "id");
5
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
6
+ const body = await readBody(event);
7
+ if (!body?.content) throw createError({ statusCode: 400, statusMessage: "missing content" });
8
+ const response = await fetch(`${cfg.baseUrl}/v1/conversations/${id}/messages`, {
9
+ method: "POST",
10
+ headers: agentRuntimeHeaders(cfg),
11
+ body: JSON.stringify({ content: body.content, context: body.context, language: body.language })
12
+ });
13
+ if (!response.ok) {
14
+ throw createError({
15
+ statusCode: response.status,
16
+ statusMessage: await response.text()
17
+ });
18
+ }
19
+ return await response.json();
20
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * GET `${apiPrefix}/conversations/:id/stream` — pipes the upstream
3
+ * Server-Sent Events stream from agent-runtime straight back to the browser.
4
+ *
5
+ * Closing the client connection aborts the upstream fetch so we don't leave
6
+ * orphaned conversations hanging.
7
+ */
8
+ declare const _default: any;
9
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import { Readable } from "node:stream";
2
+ import { agentRuntime } from "../../../utils/agent-runtime.js";
3
+ export default defineEventHandler(async (event) => {
4
+ const cfg = agentRuntime();
5
+ const id = getRouterParam(event, "id");
6
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
7
+ const controller = new AbortController();
8
+ event.node.req.on("close", () => controller.abort());
9
+ const upstream = await fetch(`${cfg.baseUrl}/v1/conversations/${id}/stream`, {
10
+ method: "GET",
11
+ headers: {
12
+ "X-Agent-Runtime-App-Key": cfg.appKey,
13
+ accept: "text/event-stream"
14
+ },
15
+ signal: controller.signal
16
+ });
17
+ if (!upstream.ok || !upstream.body) {
18
+ throw createError({
19
+ statusCode: upstream.status || 502,
20
+ statusMessage: `agent-runtime stream failed: ${upstream.status} ${upstream.statusText}`
21
+ });
22
+ }
23
+ setHeader(event, "content-type", "text/event-stream");
24
+ setHeader(event, "cache-control", "no-cache, no-transform");
25
+ setHeader(event, "connection", "keep-alive");
26
+ setHeader(event, "x-accel-buffering", "no");
27
+ return sendStream(event, Readable.fromWeb(upstream.body));
28
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { agentRuntime } from "../../utils/agent-runtime.js";
2
+ export default defineEventHandler(async (event) => {
3
+ const cfg = agentRuntime();
4
+ const id = getRouterParam(event, "id");
5
+ if (!id) throw createError({ statusCode: 400, statusMessage: "missing conversation id" });
6
+ const response = await fetch(`${cfg.baseUrl}/v1/conversations/${id}`, {
7
+ method: "DELETE",
8
+ headers: { "X-Agent-Runtime-App-Key": cfg.appKey }
9
+ });
10
+ if (!response.ok) {
11
+ throw createError({
12
+ statusCode: response.status,
13
+ statusMessage: await response.text()
14
+ });
15
+ }
16
+ setResponseStatus(event, 204);
17
+ return null;
18
+ });
@@ -0,0 +1,7 @@
1
+ /**
2
+ * POST `${apiPrefix}/conversations` — opens a new conversation against the
3
+ * configured app, optionally seeded with an `env` map (which the harness
4
+ * uses to populate the workspace environment) and a model override.
5
+ */
6
+ declare const _default: any;
7
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import { agentRuntime, agentRuntimeHeaders } from "../utils/agent-runtime.js";
2
+ export default defineEventHandler(async (event) => {
3
+ const cfg = agentRuntime();
4
+ const body = await readBody(event).catch(() => ({}));
5
+ const response = await fetch(`${cfg.baseUrl}/v1/conversations`, {
6
+ method: "POST",
7
+ headers: agentRuntimeHeaders(cfg),
8
+ body: JSON.stringify({ appId: cfg.appId, env: body.env ?? {}, model: body.model, language: body.language })
9
+ });
10
+ if (!response.ok) {
11
+ throw createError({
12
+ statusCode: response.status,
13
+ statusMessage: await response.text()
14
+ });
15
+ }
16
+ return await response.json();
17
+ });
@@ -0,0 +1,12 @@
1
+ import { type AgentRuntimeResolvedConfig } from '../../../shared.js';
2
+ /** Resolved server-side configuration for talking to agent-runtime. */
3
+ export type AgentRuntimeRuntime = AgentRuntimeResolvedConfig;
4
+ /**
5
+ * Read the agent-runtime section of `runtimeConfig`, validating that the app key
6
+ * has been provided. Throws a typed Nitro 500 otherwise so the proxy routes
7
+ * surface a clear error instead of silently forwarding an unauthenticated
8
+ * request.
9
+ */
10
+ export declare const agentRuntime: () => AgentRuntimeRuntime;
11
+ /** Build the standard JSON request headers, including the app key. */
12
+ export declare const agentRuntimeHeaders: (cfg: AgentRuntimeRuntime, extra?: Record<string, string>) => Record<string, string>;
@@ -0,0 +1,12 @@
1
+ import { createAgentRuntimeRequestHeaders, resolveAgentRuntimeConfig } from "../../../shared";
2
+ export const agentRuntime = () => {
3
+ try {
4
+ return resolveAgentRuntimeConfig(useRuntimeConfig().agentRuntime);
5
+ } catch (error) {
6
+ throw createError({
7
+ statusCode: 500,
8
+ statusMessage: error instanceof Error ? `${error.message}. Set it via env, runtimeConfig.agentRuntime.appKey, or the module options.` : "[agent-runtime] AGENT_RUNTIME_APP_KEY is not configured. Set it via env, runtimeConfig.agentRuntime.appKey, or the module options."
9
+ });
10
+ }
11
+ };
12
+ export const agentRuntimeHeaders = (cfg, extra = {}) => createAgentRuntimeRequestHeaders(cfg, extra);
@@ -0,0 +1,16 @@
1
+ export interface AgentRuntimeFileLike {
2
+ name?: string | null;
3
+ relPath?: string | null;
4
+ mimeType?: string | null;
5
+ }
6
+ export type AgentRuntimeFilePreviewKind = 'image' | 'pdf' | 'text' | 'download';
7
+ export declare const toAgentRuntimeWorkspaceRelativePath: (uri: string) => string | null;
8
+ export declare const resolveAgentRuntimeWorkspaceUri: (uri: string, resolveWorkspacePath?: (relPath: string) => string | null | undefined) => string | null;
9
+ export declare const isAgentRuntimeImageMimeType: (mimeType: string | null | undefined) => boolean;
10
+ export declare const isAgentRuntimePdfMimeType: (mimeType: string | null | undefined) => boolean;
11
+ export declare const isAgentRuntimeTextMimeType: (mimeType: string | null | undefined) => boolean;
12
+ export declare const isAgentRuntimeImagePath: (value: string | null | undefined) => boolean;
13
+ export declare const isAgentRuntimePdfPath: (value: string | null | undefined) => boolean;
14
+ export declare const isAgentRuntimeTextPath: (value: string | null | undefined) => boolean;
15
+ export declare const getAgentRuntimeFilePreviewKind: (file: AgentRuntimeFileLike) => AgentRuntimeFilePreviewKind;
16
+ export declare const canPreviewAgentRuntimeFileInline: (file: AgentRuntimeFileLike) => boolean;
@@ -0,0 +1,42 @@
1
+ const IMAGE_EXT_RE = /\.(?:png|jpe?g|gif|webp|svg|avif|bmp)(?:[?#].*)?$/i;
2
+ const PDF_EXT_RE = /\.pdf(?:[?#].*)?$/i;
3
+ const TEXT_EXT_RE = /\.(?:txt|md|json|csv|tsv|xml|ya?ml|log|html?|css|js|mjs|cjs|ts|tsx|jsx|vue|py|rb|sh|sql)(?:[?#].*)?$/i;
4
+ export const toAgentRuntimeWorkspaceRelativePath = (uri) => {
5
+ if (!uri) return null;
6
+ if (uri.startsWith("sandbox:")) return uri.slice("sandbox:".length).replace(/^\/+/, "");
7
+ if (uri.startsWith("/workspace/")) return uri.slice("/workspace/".length);
8
+ if (uri === "/workspace") return "";
9
+ if (uri.startsWith("workspace/")) return uri.slice("workspace/".length);
10
+ return null;
11
+ };
12
+ export const resolveAgentRuntimeWorkspaceUri = (uri, resolveWorkspacePath) => {
13
+ const relPath = toAgentRuntimeWorkspaceRelativePath(uri);
14
+ if (relPath === null) return null;
15
+ const resolved = resolveWorkspacePath?.(relPath);
16
+ return resolved || null;
17
+ };
18
+ export const isAgentRuntimeImageMimeType = (mimeType) => typeof mimeType === "string" && /^image\//i.test(mimeType);
19
+ export const isAgentRuntimePdfMimeType = (mimeType) => typeof mimeType === "string" && mimeType.toLowerCase() === "application/pdf";
20
+ export const isAgentRuntimeTextMimeType = (mimeType) => {
21
+ if (typeof mimeType !== "string" || !mimeType) {
22
+ return false;
23
+ }
24
+ const normalized = mimeType.toLowerCase();
25
+ return normalized.startsWith("text/") || normalized === "application/json" || normalized === "application/ld+json" || normalized === "application/xml" || normalized === "application/yaml" || normalized === "application/x-yaml";
26
+ };
27
+ export const isAgentRuntimeImagePath = (value) => typeof value === "string" && IMAGE_EXT_RE.test(value);
28
+ export const isAgentRuntimePdfPath = (value) => typeof value === "string" && PDF_EXT_RE.test(value);
29
+ export const isAgentRuntimeTextPath = (value) => typeof value === "string" && TEXT_EXT_RE.test(value);
30
+ export const getAgentRuntimeFilePreviewKind = (file) => {
31
+ if (isAgentRuntimeImageMimeType(file.mimeType) || isAgentRuntimeImagePath(file.name) || isAgentRuntimeImagePath(file.relPath)) {
32
+ return "image";
33
+ }
34
+ if (isAgentRuntimePdfMimeType(file.mimeType) || isAgentRuntimePdfPath(file.name) || isAgentRuntimePdfPath(file.relPath)) {
35
+ return "pdf";
36
+ }
37
+ if (isAgentRuntimeTextMimeType(file.mimeType) || isAgentRuntimeTextPath(file.name) || isAgentRuntimeTextPath(file.relPath)) {
38
+ return "text";
39
+ }
40
+ return "download";
41
+ };
42
+ export const canPreviewAgentRuntimeFileInline = (file) => getAgentRuntimeFilePreviewKind(file) !== "download";
@@ -0,0 +1,9 @@
1
+ export { type AppAuth, type AppEnvField, type AppInfo, type ChatStatus, type FileEntry, type SendOptions, type UIMessage, type UiAction, type UseAgentRuntime } from '../dist/runtime/composables/useAgentRuntime.js'
2
+
3
+ export { type AgentRuntimeMarkdownRenderOptions } from '../dist/runtime/composables/useAgentRuntimeMarkdown.js'
4
+
5
+ export { type AgentRuntimeFileLike, type AgentRuntimeFilePreviewKind } from '../dist/runtime/utils/files.js'
6
+
7
+ export { default } from './module.mjs'
8
+
9
+ export { type ModuleOptions, type PrivateAgentRuntimeConfig, type PublicAgentRuntimeConfig } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@d4y/agent-runtime-nuxt",
3
+ "version": "0.1.0",
4
+ "description": "Headless Nuxt module that connects a Nuxt app to an agent-runtime server. Ships server-side proxy routes (so your X-Agent-Runtime-App-Key never leaves the server) and a single composable, useAgentRuntime(), that exposes a typed chat client.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/digital4you/agent-runtime.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "registry": "https://registry.npmjs.org/"
14
+ },
15
+ "main": "./src/module.ts",
16
+ "types": "./src/module.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./src/module.ts",
20
+ "import": "./src/module.ts"
21
+ },
22
+ "./frontend": {
23
+ "types": "./src/frontend.ts",
24
+ "import": "./src/frontend.ts"
25
+ },
26
+ "./shared": {
27
+ "types": "./src/shared.ts",
28
+ "import": "./src/shared.ts"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "src"
34
+ ],
35
+ "keywords": [
36
+ "nuxt",
37
+ "nuxt-module",
38
+ "agent-runtime",
39
+ "chat",
40
+ "ai",
41
+ "agent"
42
+ ],
43
+ "scripts": {
44
+ "prepack": "nuxt-module-build build",
45
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare",
46
+ "typecheck": "tsc --noEmit -p tsconfig.json"
47
+ },
48
+ "dependencies": {
49
+ "@nuxt/kit": "^4.4.2",
50
+ "ai": "^6.0.168",
51
+ "defu": "^6.1.4",
52
+ "markdown-it": "^14.1.1"
53
+ },
54
+ "devDependencies": {
55
+ "@nuxt/module-builder": "^1.0.2",
56
+ "@nuxt/schema": "^4.4.2",
57
+ "@types/markdown-it": "^14.1.2",
58
+ "h3": "^1.15.11",
59
+ "nuxt": "^4.4.2",
60
+ "typescript": "^6.0.2",
61
+ "vue": "^3.5.32",
62
+ "vue-tsc": "^3.2.7"
63
+ },
64
+ "peerDependencies": {
65
+ "nuxt": "^3.13.0 || ^4.0.0"
66
+ }
67
+ }
@@ -0,0 +1,16 @@
1
+ export type { AgentRuntimeMarkdownRenderOptions } from './runtime/composables/useAgentRuntimeMarkdown'
2
+ export type { AgentRuntimeFileLike, AgentRuntimeFilePreviewKind } from './runtime/utils/files'
3
+ export { default as AgentRuntimeArtifactPreview } from './runtime/components/AgentRuntimeArtifactPreview.vue'
4
+ export { createAgentRuntimeMarkdownRenderer, useAgentRuntimeMarkdown } from './runtime/composables/useAgentRuntimeMarkdown'
5
+ export {
6
+ canPreviewAgentRuntimeFileInline,
7
+ getAgentRuntimeFilePreviewKind,
8
+ isAgentRuntimeImageMimeType,
9
+ isAgentRuntimeImagePath,
10
+ isAgentRuntimePdfMimeType,
11
+ isAgentRuntimePdfPath,
12
+ isAgentRuntimeTextMimeType,
13
+ isAgentRuntimeTextPath,
14
+ resolveAgentRuntimeWorkspaceUri,
15
+ toAgentRuntimeWorkspaceRelativePath,
16
+ } from './runtime/utils/files'
package/src/module.ts ADDED
@@ -0,0 +1,155 @@
1
+ import { defineNuxtModule, createResolver, addImportsDir, addServerHandler, addTypeTemplate } from '@nuxt/kit'
2
+ import { defu } from 'defu'
3
+
4
+ // Re-export the public composable surface so consumers can `import type
5
+ // { UIMessage, AppInfo, … } from '@d4y/agent-runtime-nuxt'` without reaching into
6
+ // `runtime/`. The composable itself is auto-imported via addImportsDir.
7
+ export type {
8
+ UseAgentRuntime,
9
+ UIMessage,
10
+ AppInfo,
11
+ AppAuth,
12
+ AppEnvField,
13
+ FileEntry,
14
+ UiAction,
15
+ SendOptions,
16
+ ChatStatus
17
+ } from './runtime/composables/useAgentRuntime'
18
+ export type { AgentRuntimeMarkdownRenderOptions } from './runtime/composables/useAgentRuntimeMarkdown'
19
+ export type { AgentRuntimeFileLike, AgentRuntimeFilePreviewKind } from './runtime/utils/files'
20
+
21
+ /**
22
+ * Module options for `@d4y/agent-runtime-nuxt`.
23
+ *
24
+ * Every field is optional at config time — unset values fall back to the
25
+ * matching `AGENT_RUNTIME_*` environment variable at runtime, so the same build
26
+ * artifact works across environments without rebuilding.
27
+ */
28
+ export interface ModuleOptions {
29
+ /**
30
+ * Base URL of the agent-runtime HTTP server (no trailing slash required).
31
+ *
32
+ * Falls back to `process.env.AGENT_RUNTIME_URL` then `http://127.0.0.1:18791`.
33
+ */
34
+ baseUrl?: string
35
+
36
+ /**
37
+ * App key used to authenticate against agent-runtime (`X-Agent-Runtime-App-Key` header).
38
+ *
39
+ * **Server-only secret.** Never exposed to the browser; the module only
40
+ * forwards it from the proxy routes it registers.
41
+ *
42
+ * Falls back to `process.env.AGENT_RUNTIME_APP_KEY`. Required at runtime — the
43
+ * module will throw a 500 from any proxy route if missing.
44
+ */
45
+ appKey?: string
46
+
47
+ /**
48
+ * App ID to bind every conversation to (must match an app registered in
49
+ * the agent-runtime `apps/` directory).
50
+ *
51
+ * Falls back to `process.env.AGENT_RUNTIME_APP_ID` then `omnisearch`.
52
+ */
53
+ appId?: string
54
+
55
+ /**
56
+ * URL prefix for the auto-registered Nitro proxy routes. Change it if you
57
+ * need to disambiguate from another module on the same `/api/...` namespace.
58
+ *
59
+ * Default: `/api/agent-runtime`.
60
+ */
61
+ apiPrefix?: string
62
+ }
63
+
64
+ /** Public runtime-config shape exposed to the browser (path data only). */
65
+ export interface PublicAgentRuntimeConfig {
66
+ /** Same value as `apiPrefix` from module options; needed by `useAgentRuntime` to build URLs. */
67
+ apiPrefix: string
68
+ /** App ID, used by the composable to scope `localStorage` keys. */
69
+ appId: string
70
+ }
71
+
72
+ /** Private runtime-config shape (server-only). */
73
+ export interface PrivateAgentRuntimeConfig {
74
+ baseUrl: string
75
+ appKey: string
76
+ appId: string
77
+ }
78
+
79
+ declare module '@nuxt/schema' {
80
+ interface RuntimeConfig {
81
+ agentRuntime: PrivateAgentRuntimeConfig
82
+ }
83
+ interface PublicRuntimeConfig {
84
+ agentRuntime: PublicAgentRuntimeConfig
85
+ }
86
+ }
87
+
88
+ const DEFAULTS: Required<Pick<ModuleOptions, 'baseUrl' | 'appId' | 'apiPrefix'>> = {
89
+ baseUrl: 'http://127.0.0.1:18791',
90
+ appId: 'omnisearch',
91
+ apiPrefix: '/api/agent-runtime'
92
+ }
93
+
94
+ export default defineNuxtModule<ModuleOptions>({
95
+ meta: {
96
+ name: '@d4y/agent-runtime-nuxt',
97
+ configKey: 'agentRuntime',
98
+ compatibility: { nuxt: '>=3.13.0' }
99
+ },
100
+ defaults: {},
101
+ setup(userOptions, nuxt) {
102
+ const resolver = createResolver(import.meta.url)
103
+
104
+ const baseUrl = (userOptions.baseUrl ?? process.env.AGENT_RUNTIME_URL ?? DEFAULTS.baseUrl).replace(/\/+$/, '')
105
+ const appKey = userOptions.appKey ?? process.env.AGENT_RUNTIME_APP_KEY ?? ''
106
+ const appId = userOptions.appId ?? process.env.AGENT_RUNTIME_APP_ID ?? DEFAULTS.appId
107
+ const apiPrefix = (userOptions.apiPrefix ?? DEFAULTS.apiPrefix).replace(/\/+$/, '')
108
+
109
+ nuxt.options.runtimeConfig.agentRuntime = defu(nuxt.options.runtimeConfig.agentRuntime, {
110
+ baseUrl,
111
+ appKey,
112
+ appId
113
+ })
114
+
115
+ nuxt.options.runtimeConfig.public.agentRuntime = defu(nuxt.options.runtimeConfig.public.agentRuntime, {
116
+ apiPrefix,
117
+ appId
118
+ })
119
+
120
+ // Composable auto-import — `useAgentRuntime()` is available everywhere.
121
+ addImportsDir(resolver.resolve('./runtime/composables'))
122
+
123
+ // Generate a `.d.ts` shim that re-exports the public types from the
124
+ // module so IDEs see them without the consumer touching tsconfig paths.
125
+ addTypeTemplate({
126
+ filename: 'types/agent-runtime.d.ts',
127
+ getContents: () => [
128
+ `// Auto-generated by @d4y/agent-runtime-nuxt`,
129
+ `export type { UseAgentRuntime, AppInfo, AppAuth, AppEnvField, FileEntry, UiAction, SendOptions, ChatStatus } from '${resolver.resolve('./runtime/composables/useAgentRuntime')}'`,
130
+ `export type { AgentRuntimeMarkdownRenderOptions } from '${resolver.resolve('./runtime/composables/useAgentRuntimeMarkdown')}'`,
131
+ `export type { AgentRuntimeFileLike, AgentRuntimeFilePreviewKind } from '${resolver.resolve('./runtime/utils/files')}'`,
132
+ ''
133
+ ].join('\n')
134
+ })
135
+
136
+ // Register every proxy route under the configured prefix.
137
+ const route = (suffix: string, handler: string, method?: 'get' | 'post' | 'delete') =>
138
+ addServerHandler({
139
+ route: `${apiPrefix}${suffix}`,
140
+ method,
141
+ handler: resolver.resolve(`./runtime/server/api/${handler}`)
142
+ })
143
+
144
+ route('/app', 'app.get', 'get')
145
+ route('/conversations', 'conversations.post', 'post')
146
+ route('/conversations/:id', 'conversations/[id].delete', 'delete')
147
+ route('/conversations/:id/history', 'conversations/[id]/history.get', 'get')
148
+ route('/conversations/:id/stream', 'conversations/[id]/stream.get', 'get')
149
+ route('/conversations/:id/messages', 'conversations/[id]/messages.post', 'post')
150
+ route('/conversations/:id/abort', 'conversations/[id]/abort.post', 'post')
151
+ route('/conversations/:id/env', 'conversations/[id]/env.post', 'post')
152
+ route('/conversations/:id/files', 'conversations/[id]/files.get', 'get')
153
+ route('/conversations/:id/files/raw/**', 'conversations/[id]/files/raw/[...path].get', 'get')
154
+ }
155
+ })
@@ -0,0 +1,8 @@
1
+ declare const defineEventHandler: typeof import('h3').defineEventHandler
2
+ declare const createError: typeof import('h3').createError
3
+ declare const getRouterParam: typeof import('h3').getRouterParam
4
+ declare const setHeader: typeof import('h3').setHeader
5
+ declare const sendStream: typeof import('h3').sendStream
6
+ declare const readBody: typeof import('h3').readBody
7
+ declare const setResponseStatus: typeof import('h3').setResponseStatus
8
+ declare const useRuntimeConfig: () => any