@d4y/agent-runtime-nuxt 0.1.3 → 0.1.7
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/README.md +27 -4
- package/dist/module.json +1 -1
- package/dist/runtime/components/AgentRuntimeMarkdown.d.vue.ts +10 -0
- package/dist/runtime/components/AgentRuntimeMarkdown.vue +17 -7
- package/dist/runtime/components/AgentRuntimeMarkdown.vue.d.ts +10 -0
- package/dist/runtime/composables/useAgentRuntime.d.ts +39 -0
- package/dist/runtime/composables/useAgentRuntime.js +71 -4
- package/dist/runtime/composables/useAgentRuntimeMarkdown.d.ts +5 -0
- package/dist/runtime/composables/useAgentRuntimeMarkdown.js +11 -8
- package/dist/runtime/server/api/conversations/[id]/messages.post.js +6 -1
- package/dist/runtime/server/api/conversations.post.js +7 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -108,7 +108,7 @@ The composable returns AI-SDK / Nuxt UI compatible `UIMessage` shapes, so
|
|
|
108
108
|
| `/conversations/:id` | DELETE | Delete a persisted conversation. |
|
|
109
109
|
| `/conversations/:id/history` | GET | Return the persisted conversation history. |
|
|
110
110
|
| `/conversations/:id/stream` | GET | Pipes the upstream SSE stream verbatim. |
|
|
111
|
-
| `/conversations/:id/messages` | POST | Append a user turn. Body: `{ content, context? }`.
|
|
111
|
+
| `/conversations/:id/messages` | POST | Append a user turn. Body: `{ content, context?, requestOptions? }`. |
|
|
112
112
|
| `/conversations/:id/abort` | POST | Cancel the in-flight agent run. |
|
|
113
113
|
| `/conversations/:id/env` | POST | Patch workspace env. Body: `{ env, merge? }`. |
|
|
114
114
|
| `/conversations/:id/files` | GET | List workspace files. |
|
|
@@ -160,9 +160,32 @@ workspace via `POST /conversations/:id/env`, which retriggers any matching
|
|
|
160
160
|
#### `send(text, options?)`
|
|
161
161
|
|
|
162
162
|
Lazily calls `start()` if no conversation exists. The displayed user bubble
|
|
163
|
-
always shows `text
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
always shows `text`.
|
|
164
|
+
|
|
165
|
+
Use `requestOptions` for provider-side controls such as Qwen/vLLM
|
|
166
|
+
`chat_template_kwargs`:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
await chat.start({
|
|
170
|
+
requestOptions: {
|
|
171
|
+
temperature: 0.7,
|
|
172
|
+
topP: 0.8,
|
|
173
|
+
presencePenalty: 1.5
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
await chat.send(input.value, {
|
|
178
|
+
requestOptions: {
|
|
179
|
+
extraBody: {
|
|
180
|
+
top_k: 20,
|
|
181
|
+
chat_template_kwargs: { enable_thinking: false }
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
`rewriteContent` is still available as a fallback when a model expects prompt
|
|
188
|
+
text toggles rather than provider payload fields:
|
|
166
189
|
|
|
167
190
|
```ts
|
|
168
191
|
await chat.send(input.value, {
|
package/dist/module.json
CHANGED
|
@@ -4,6 +4,11 @@ type __VLS_Props = {
|
|
|
4
4
|
streaming?: boolean;
|
|
5
5
|
resolveWorkspacePath?: ((relPath: string) => string | null | undefined) | null;
|
|
6
6
|
resolveWorkspacePreviewPath?: ((relPath: string) => string | null | undefined) | null;
|
|
7
|
+
previewLinkLabel?: string;
|
|
8
|
+
downloadLinkLabel?: string;
|
|
9
|
+
pdfPreviewTitleLabel?: string;
|
|
10
|
+
htmlPreviewTitleLabel?: string;
|
|
11
|
+
showPdfEmbedToolbar?: boolean;
|
|
7
12
|
};
|
|
8
13
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
14
|
renderedChange: (rendered: boolean) => any;
|
|
@@ -11,6 +16,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
16
|
onRenderedChange?: ((rendered: boolean) => any) | undefined;
|
|
12
17
|
}>, {
|
|
13
18
|
class: string | Record<string, boolean> | string[];
|
|
19
|
+
previewLinkLabel: string;
|
|
20
|
+
downloadLinkLabel: string;
|
|
21
|
+
pdfPreviewTitleLabel: string;
|
|
22
|
+
htmlPreviewTitleLabel: string;
|
|
23
|
+
showPdfEmbedToolbar: boolean;
|
|
14
24
|
streaming: boolean;
|
|
15
25
|
resolveWorkspacePath: ((relPath: string) => string | null | undefined) | null;
|
|
16
26
|
resolveWorkspacePreviewPath: ((relPath: string) => string | null | undefined) | null;
|
|
@@ -8,13 +8,23 @@ const props = defineProps({
|
|
|
8
8
|
class: { type: [String, Object, Array], required: false, default: "" },
|
|
9
9
|
streaming: { type: Boolean, required: false, default: false },
|
|
10
10
|
resolveWorkspacePath: { type: [Function, null], required: false, default: null },
|
|
11
|
-
resolveWorkspacePreviewPath: { type: [Function, null], required: false, default: null }
|
|
11
|
+
resolveWorkspacePreviewPath: { type: [Function, null], required: false, default: null },
|
|
12
|
+
previewLinkLabel: { type: String, required: false, default: "Preview" },
|
|
13
|
+
downloadLinkLabel: { type: String, required: false, default: "Download" },
|
|
14
|
+
pdfPreviewTitleLabel: { type: String, required: false, default: "PDF preview" },
|
|
15
|
+
htmlPreviewTitleLabel: { type: String, required: false, default: "HTML preview" },
|
|
16
|
+
showPdfEmbedToolbar: { type: Boolean, required: false, default: false }
|
|
12
17
|
});
|
|
13
|
-
const
|
|
18
|
+
const renderer = computed(() => useAgentRuntimeMarkdown({
|
|
14
19
|
resolveWorkspacePath: (relPath) => props.resolveWorkspacePath?.(relPath) ?? null,
|
|
15
|
-
resolveWorkspacePreviewPath: (relPath) => props.resolveWorkspacePreviewPath?.(relPath) ?? null
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
resolveWorkspacePreviewPath: (relPath) => props.resolveWorkspacePreviewPath?.(relPath) ?? null,
|
|
21
|
+
previewLinkLabel: props.previewLinkLabel,
|
|
22
|
+
downloadLinkLabel: props.downloadLinkLabel,
|
|
23
|
+
pdfPreviewTitleLabel: props.pdfPreviewTitleLabel,
|
|
24
|
+
htmlPreviewTitleLabel: props.htmlPreviewTitleLabel,
|
|
25
|
+
showPdfEmbedToolbar: props.showPdfEmbedToolbar
|
|
26
|
+
}));
|
|
27
|
+
const html = computed(() => props.text ? renderer.value.render(props.text) : "");
|
|
18
28
|
const dialogOpen = ref(false);
|
|
19
29
|
const dialogFile = ref(null);
|
|
20
30
|
const dialogPreviewSrc = ref(null);
|
|
@@ -57,7 +67,7 @@ watch(rendered, async (value) => {
|
|
|
57
67
|
<div
|
|
58
68
|
v-if="rendered"
|
|
59
69
|
class="agent-runtime-markdown"
|
|
60
|
-
:class="
|
|
70
|
+
:class="props.class"
|
|
61
71
|
@click="onClick"
|
|
62
72
|
v-html="
|
|
63
73
|
html
|
|
@@ -73,5 +83,5 @@ watch(rendered, async (value) => {
|
|
|
73
83
|
</template>
|
|
74
84
|
|
|
75
85
|
<style scoped>
|
|
76
|
-
.agent-runtime-markdown{line-height:1.65}.agent-runtime-markdown
|
|
86
|
+
.agent-runtime-markdown{line-height:1.65}.agent-runtime-markdown :deep(.agent-runtime-md-image-link){cursor:zoom-in;display:inline-block}.agent-runtime-markdown :deep(.agent-runtime-md-image){border-radius:.95rem;display:block;max-height:20rem;max-width:min(100%,30rem);-o-object-fit:contain;object-fit:contain}.agent-runtime-markdown :deep(.agent-runtime-md-file-link){color:inherit;text-decoration:underline;text-underline-offset:.18em}.agent-runtime-markdown :deep(.agent-runtime-md-html-shell),.agent-runtime-markdown :deep(.agent-runtime-md-pdf-shell){background:color-mix(in srgb,var(--ui-bg-elevated,rgba(248,250,252,.9)) 82%,transparent);border:1px solid color-mix(in srgb,var(--ui-border,rgba(148,163,184,.28)) 80%,transparent);border-radius:1rem;display:block;margin-top:.75rem;overflow:hidden}.agent-runtime-markdown :deep(.agent-runtime-md-embed-toolbar){align-items:center;border-bottom:1px solid color-mix(in srgb,var(--ui-border,rgba(148,163,184,.28)) 70%,transparent);display:flex;flex-wrap:wrap;font-size:.75rem;gap:.75rem;justify-content:space-between;padding:.75rem .9rem}.agent-runtime-markdown :deep(.agent-runtime-md-embed-label){font-family:var(--font-mono,ui-monospace,monospace);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-runtime-markdown :deep(.agent-runtime-md-embed-actions){display:inline-flex;flex-wrap:wrap;gap:.5rem}.agent-runtime-markdown :deep(.agent-runtime-md-download-link),.agent-runtime-markdown :deep(.agent-runtime-md-preview-link){color:inherit;text-decoration:underline;text-underline-offset:.18em}.agent-runtime-markdown :deep(.agent-runtime-md-preview-link[data-agent-runtime-preview=true]){cursor:zoom-in}.agent-runtime-markdown :deep(.agent-runtime-md-html-frame),.agent-runtime-markdown :deep(.agent-runtime-md-pdf-frame){background:color-mix(in srgb,var(--ui-bg,hsla(0,0%,100%,.94)) 85%,transparent);border:0;display:block;height:22rem;width:100%}
|
|
77
87
|
</style>
|
|
@@ -4,6 +4,11 @@ type __VLS_Props = {
|
|
|
4
4
|
streaming?: boolean;
|
|
5
5
|
resolveWorkspacePath?: ((relPath: string) => string | null | undefined) | null;
|
|
6
6
|
resolveWorkspacePreviewPath?: ((relPath: string) => string | null | undefined) | null;
|
|
7
|
+
previewLinkLabel?: string;
|
|
8
|
+
downloadLinkLabel?: string;
|
|
9
|
+
pdfPreviewTitleLabel?: string;
|
|
10
|
+
htmlPreviewTitleLabel?: string;
|
|
11
|
+
showPdfEmbedToolbar?: boolean;
|
|
7
12
|
};
|
|
8
13
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
14
|
renderedChange: (rendered: boolean) => any;
|
|
@@ -11,6 +16,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
11
16
|
onRenderedChange?: ((rendered: boolean) => any) | undefined;
|
|
12
17
|
}>, {
|
|
13
18
|
class: string | Record<string, boolean> | string[];
|
|
19
|
+
previewLinkLabel: string;
|
|
20
|
+
downloadLinkLabel: string;
|
|
21
|
+
pdfPreviewTitleLabel: string;
|
|
22
|
+
htmlPreviewTitleLabel: string;
|
|
23
|
+
showPdfEmbedToolbar: boolean;
|
|
14
24
|
streaming: boolean;
|
|
15
25
|
resolveWorkspacePath: ((relPath: string) => string | null | undefined) | null;
|
|
16
26
|
resolveWorkspacePreviewPath: ((relPath: string) => string | null | undefined) | null;
|
|
@@ -38,6 +38,22 @@ export interface UiAction {
|
|
|
38
38
|
payload: unknown;
|
|
39
39
|
at: number;
|
|
40
40
|
}
|
|
41
|
+
export interface ContextUsage {
|
|
42
|
+
tokens: number | null;
|
|
43
|
+
contextWindow: number;
|
|
44
|
+
percent: number | null;
|
|
45
|
+
}
|
|
46
|
+
export interface CompactionLogEntry {
|
|
47
|
+
phase: 'start' | 'end';
|
|
48
|
+
at: number;
|
|
49
|
+
reason?: string;
|
|
50
|
+
tokensBefore?: number;
|
|
51
|
+
tokensAfter?: number;
|
|
52
|
+
compacted?: boolean;
|
|
53
|
+
aborted?: boolean;
|
|
54
|
+
willRetry?: boolean;
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
41
57
|
/** Workspace file entry, mirrors the backend response. */
|
|
42
58
|
export interface FileEntry {
|
|
43
59
|
name: string;
|
|
@@ -47,6 +63,19 @@ export interface FileEntry {
|
|
|
47
63
|
mimeType: string;
|
|
48
64
|
kind: 'image' | 'html' | 'pdf' | 'download';
|
|
49
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Generic provider request options forwarded to the runtime.
|
|
68
|
+
* `extraBody` is merged verbatim into the provider payload, which makes this
|
|
69
|
+
* suitable for model-specific flags such as Qwen's `chat_template_kwargs`.
|
|
70
|
+
*/
|
|
71
|
+
export interface RequestOptions {
|
|
72
|
+
temperature?: number;
|
|
73
|
+
maxTokens?: number;
|
|
74
|
+
topP?: number;
|
|
75
|
+
presencePenalty?: number;
|
|
76
|
+
frequencyPenalty?: number;
|
|
77
|
+
extraBody?: Record<string, unknown>;
|
|
78
|
+
}
|
|
50
79
|
/** Per-turn options for `send`. */
|
|
51
80
|
export interface SendOptions {
|
|
52
81
|
/**
|
|
@@ -62,11 +91,15 @@ export interface SendOptions {
|
|
|
62
91
|
rewriteContent?: (text: string) => string;
|
|
63
92
|
/** Optional language override for this turn / conversation, e.g. `en` or `de-CH`. */
|
|
64
93
|
language?: string;
|
|
94
|
+
/** Optional provider request overrides for this turn only. */
|
|
95
|
+
requestOptions?: RequestOptions;
|
|
65
96
|
}
|
|
66
97
|
/** Options for `start`. */
|
|
67
98
|
export interface StartOptions {
|
|
68
99
|
/** Optional language override for the newly created conversation. */
|
|
69
100
|
language?: string;
|
|
101
|
+
/** Optional default provider request options for the conversation. */
|
|
102
|
+
requestOptions?: RequestOptions;
|
|
70
103
|
}
|
|
71
104
|
/** Return shape of {@link useAgentRuntime}. All members are reactive. */
|
|
72
105
|
export interface UseAgentRuntime {
|
|
@@ -80,6 +113,12 @@ export interface UseAgentRuntime {
|
|
|
80
113
|
error: Ref<Error | null>;
|
|
81
114
|
/** Most recent UI-action events, newest first, capped at 50. */
|
|
82
115
|
uiActions: Ref<UiAction[]>;
|
|
116
|
+
/** Latest context usage sample from the active PI session. */
|
|
117
|
+
contextUsage: Ref<ContextUsage | null>;
|
|
118
|
+
/** True iff a compaction run is currently in progress. */
|
|
119
|
+
compactionInProgress: Ref<boolean>;
|
|
120
|
+
/** Most recent compaction events, newest first. */
|
|
121
|
+
compactionLog: Ref<CompactionLogEntry[]>;
|
|
83
122
|
/** Active app manifest. `null` until the first `onMounted` fetch resolves. */
|
|
84
123
|
app: Ref<AppInfo | null>;
|
|
85
124
|
/** Current auth values (persisted in localStorage, scoped per appId). */
|
|
@@ -43,6 +43,9 @@ export const useAgentRuntime = () => {
|
|
|
43
43
|
const status = ref("idle");
|
|
44
44
|
const error = ref(null);
|
|
45
45
|
const uiActions = ref([]);
|
|
46
|
+
const contextUsage = ref(null);
|
|
47
|
+
const compactionInProgress = ref(false);
|
|
48
|
+
const compactionLog = ref([]);
|
|
46
49
|
const app = ref(null);
|
|
47
50
|
const auth = ref(emptyAuth());
|
|
48
51
|
const authReady = computed(() => computeAuthReady(auth.value, app.value));
|
|
@@ -121,6 +124,12 @@ export const useAgentRuntime = () => {
|
|
|
121
124
|
return { ...msg, parts };
|
|
122
125
|
});
|
|
123
126
|
};
|
|
127
|
+
const normalizePercent = (value) => Math.max(0, Math.min(100, value > 1 ? value : value * 100));
|
|
128
|
+
const toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
129
|
+
const toNullableNumber = (value) => value === null ? null : toNumber(value);
|
|
130
|
+
const pushCompactionLog = (entry) => {
|
|
131
|
+
compactionLog.value = [entry, ...compactionLog.value].slice(0, 20);
|
|
132
|
+
};
|
|
124
133
|
const onSseEvent = (eventName, data) => {
|
|
125
134
|
switch (eventName) {
|
|
126
135
|
case "agent_start":
|
|
@@ -148,23 +157,66 @@ export const useAgentRuntime = () => {
|
|
|
148
157
|
type: `tool-${d.toolName}`,
|
|
149
158
|
toolCallId: d.toolCallId,
|
|
150
159
|
state: d.isError ? "output-error" : "output-available",
|
|
151
|
-
output: d.isError ? void 0 :
|
|
152
|
-
errorText: d.isError ? "Tool returned an error" : void 0
|
|
160
|
+
output: d.isError ? void 0 : d.output,
|
|
161
|
+
errorText: d.isError ? d.errorText ?? "Tool returned an error" : void 0
|
|
153
162
|
}));
|
|
154
163
|
break;
|
|
155
164
|
}
|
|
165
|
+
case "context_usage": {
|
|
166
|
+
const d = data;
|
|
167
|
+
const tokens = toNullableNumber(d.tokens);
|
|
168
|
+
const contextWindow = toNumber(d.contextWindow);
|
|
169
|
+
if (tokens === void 0 || contextWindow === void 0) break;
|
|
170
|
+
const fallbackPercent = typeof tokens === "number" && contextWindow > 0 ? tokens / contextWindow * 100 : null;
|
|
171
|
+
const percent = toNullableNumber(d.percent) ?? fallbackPercent;
|
|
172
|
+
if (percent === void 0) break;
|
|
173
|
+
contextUsage.value = {
|
|
174
|
+
tokens,
|
|
175
|
+
contextWindow,
|
|
176
|
+
percent: typeof percent === "number" ? normalizePercent(percent) : null
|
|
177
|
+
};
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case "compaction_start": {
|
|
181
|
+
const d = data;
|
|
182
|
+
compactionInProgress.value = true;
|
|
183
|
+
pushCompactionLog({
|
|
184
|
+
phase: "start",
|
|
185
|
+
at: Date.now(),
|
|
186
|
+
reason: typeof d.reason === "string" && d.reason.trim().length > 0 ? d.reason.trim() : void 0
|
|
187
|
+
});
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
case "compaction_end": {
|
|
191
|
+
const d = data;
|
|
192
|
+
const result = d.result && typeof d.result === "object" ? d.result : null;
|
|
193
|
+
compactionInProgress.value = false;
|
|
194
|
+
pushCompactionLog({
|
|
195
|
+
phase: "end",
|
|
196
|
+
at: Date.now(),
|
|
197
|
+
reason: typeof d.reason === "string" && d.reason.trim().length > 0 ? d.reason.trim() : void 0,
|
|
198
|
+
compacted: typeof d.aborted === "boolean" ? !d.aborted && !!result : !!result,
|
|
199
|
+
aborted: typeof d.aborted === "boolean" ? d.aborted : void 0,
|
|
200
|
+
willRetry: typeof d.willRetry === "boolean" ? d.willRetry : void 0,
|
|
201
|
+
tokensBefore: toNumber(result?.tokensBefore),
|
|
202
|
+
error: typeof d.errorMessage === "string" && d.errorMessage.trim().length > 0 ? d.errorMessage : void 0
|
|
203
|
+
});
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
156
206
|
case "ui_action": {
|
|
157
207
|
const d = data;
|
|
158
208
|
uiActions.value = [{ toolCallId: d.toolCallId, type: d.type, payload: d.payload, at: Date.now() }, ...uiActions.value].slice(0, 50);
|
|
159
209
|
break;
|
|
160
210
|
}
|
|
161
211
|
case "end":
|
|
212
|
+
compactionInProgress.value = false;
|
|
162
213
|
status.value = "ready";
|
|
163
214
|
currentAssistantId = null;
|
|
164
215
|
void refreshFiles();
|
|
165
216
|
break;
|
|
166
217
|
case "error": {
|
|
167
218
|
const d = data;
|
|
219
|
+
compactionInProgress.value = false;
|
|
168
220
|
error.value = new Error(d?.message ?? "stream error");
|
|
169
221
|
status.value = "error";
|
|
170
222
|
currentAssistantId = null;
|
|
@@ -217,7 +269,11 @@ export const useAgentRuntime = () => {
|
|
|
217
269
|
error.value = null;
|
|
218
270
|
const res = await $fetch(`${apiPrefix}/conversations`, {
|
|
219
271
|
method: "POST",
|
|
220
|
-
body: {
|
|
272
|
+
body: {
|
|
273
|
+
env: buildEnvFromAuth(auth.value),
|
|
274
|
+
language: options.language,
|
|
275
|
+
requestOptions: options.requestOptions
|
|
276
|
+
}
|
|
221
277
|
});
|
|
222
278
|
conversationId.value = res.conversationId;
|
|
223
279
|
abortController?.abort();
|
|
@@ -264,7 +320,12 @@ export const useAgentRuntime = () => {
|
|
|
264
320
|
const wireContent = options.rewriteContent ? options.rewriteContent(text) : text;
|
|
265
321
|
await $fetch(`${apiPrefix}/conversations/${conversationId.value}/messages`, {
|
|
266
322
|
method: "POST",
|
|
267
|
-
body: {
|
|
323
|
+
body: {
|
|
324
|
+
content: wireContent,
|
|
325
|
+
context: options.context,
|
|
326
|
+
language: options.language,
|
|
327
|
+
requestOptions: options.requestOptions
|
|
328
|
+
}
|
|
268
329
|
}).catch((err) => {
|
|
269
330
|
error.value = err instanceof Error ? err : new Error(String(err));
|
|
270
331
|
status.value = "error";
|
|
@@ -283,6 +344,9 @@ export const useAgentRuntime = () => {
|
|
|
283
344
|
currentAssistantId = null;
|
|
284
345
|
replaceMessages([]);
|
|
285
346
|
uiActions.value = [];
|
|
347
|
+
contextUsage.value = null;
|
|
348
|
+
compactionInProgress.value = false;
|
|
349
|
+
compactionLog.value = [];
|
|
286
350
|
files.value = [];
|
|
287
351
|
status.value = "idle";
|
|
288
352
|
error.value = null;
|
|
@@ -296,6 +360,9 @@ export const useAgentRuntime = () => {
|
|
|
296
360
|
status,
|
|
297
361
|
error,
|
|
298
362
|
uiActions,
|
|
363
|
+
contextUsage,
|
|
364
|
+
compactionInProgress,
|
|
365
|
+
compactionLog,
|
|
299
366
|
app,
|
|
300
367
|
auth,
|
|
301
368
|
authReady,
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import MarkdownIt from 'markdown-it';
|
|
2
2
|
import { type AgentRuntimeAssetResolverOptions } from '../utils/files.js';
|
|
3
3
|
export interface AgentRuntimeMarkdownRenderOptions extends AgentRuntimeAssetResolverOptions {
|
|
4
|
+
previewLinkLabel?: string;
|
|
5
|
+
downloadLinkLabel?: string;
|
|
6
|
+
pdfPreviewTitleLabel?: string;
|
|
7
|
+
htmlPreviewTitleLabel?: string;
|
|
8
|
+
showPdfEmbedToolbar?: boolean;
|
|
4
9
|
}
|
|
5
10
|
export declare const createAgentRuntimeMarkdownRenderer: (options?: AgentRuntimeMarkdownRenderOptions) => MarkdownIt;
|
|
6
11
|
export declare const useAgentRuntimeMarkdown: (options?: AgentRuntimeMarkdownRenderOptions) => {
|
|
@@ -33,7 +33,7 @@ const buildImageMarkup = (md, asset, alt, title) => {
|
|
|
33
33
|
const attrs = previewAttrs(md, asset);
|
|
34
34
|
return `<a href="${safePreviewUrl}" target="_blank" rel="noopener noreferrer" class="agent-runtime-md-image-link" ${attrs}><img src="${safePreviewUrl}" alt="${safeAlt}" loading="lazy" class="agent-runtime-md-image"${titleAttr} /></a>`;
|
|
35
35
|
};
|
|
36
|
-
const buildPreviewShellMarkup = (md, asset, label) => {
|
|
36
|
+
const buildPreviewShellMarkup = (md, asset, label, options) => {
|
|
37
37
|
const previewUrl = asset.previewUrl;
|
|
38
38
|
if (!previewUrl) {
|
|
39
39
|
return buildDownloadLinkMarkup(md, asset, label);
|
|
@@ -44,16 +44,19 @@ const buildPreviewShellMarkup = (md, asset, label) => {
|
|
|
44
44
|
const shellClass = asset.kind === "pdf" ? "agent-runtime-md-pdf-shell" : "agent-runtime-md-html-shell";
|
|
45
45
|
const frameClass = asset.kind === "pdf" ? "agent-runtime-md-pdf-frame" : "agent-runtime-md-html-frame";
|
|
46
46
|
const frameAttrs = asset.kind === "pdf" ? "" : ' sandbox="" referrerpolicy="no-referrer"';
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
47
|
+
const titleLabel = asset.kind === "pdf" ? options.pdfPreviewTitleLabel ?? "PDF preview" : options.htmlPreviewTitleLabel ?? "HTML preview";
|
|
48
|
+
const title = `${titleLabel}: ${label}`;
|
|
49
|
+
const showToolbar = asset.kind !== "pdf" || options.showPdfEmbedToolbar === true;
|
|
50
|
+
const downloadButton = asset.canDownload && asset.rawUrl ? `<a href="${escapeAttr(md, asset.rawUrl)}" target="_blank" rel="noopener noreferrer" class="agent-runtime-md-download-link">${escapeAttr(md, options.downloadLinkLabel ?? "Download")}</a>` : "";
|
|
51
|
+
const toolbar = showToolbar ? `<span class="agent-runtime-md-embed-toolbar"><span class="agent-runtime-md-embed-label">${safeLabel}</span><span class="agent-runtime-md-embed-actions"><a href="${safePreviewUrl}" target="_blank" rel="noopener noreferrer" class="agent-runtime-md-preview-link" ${attrs}>${escapeAttr(md, options.previewLinkLabel ?? "Preview")}</a>${downloadButton}</span></span>` : "";
|
|
52
|
+
return `<span class="${shellClass}">${toolbar}<iframe src="${safePreviewUrl}" title="${escapeAttr(md, title)}" loading="lazy"${frameAttrs} class="${frameClass}"></iframe></span>`;
|
|
50
53
|
};
|
|
51
54
|
const toHtmlToken = (state, markup) => {
|
|
52
55
|
const token = new state.Token("html_inline", "", 0);
|
|
53
56
|
token.content = markup;
|
|
54
57
|
return token;
|
|
55
58
|
};
|
|
56
|
-
const renderWorkspaceLink = (md, asset, label) => {
|
|
59
|
+
const renderWorkspaceLink = (md, asset, label, options) => {
|
|
57
60
|
if (asset.kind === "blocked") {
|
|
58
61
|
return escapeAttr(md, label);
|
|
59
62
|
}
|
|
@@ -61,7 +64,7 @@ const renderWorkspaceLink = (md, asset, label) => {
|
|
|
61
64
|
return buildImageMarkup(md, asset, label);
|
|
62
65
|
}
|
|
63
66
|
if (asset.kind === "html" || asset.kind === "pdf") {
|
|
64
|
-
return buildPreviewShellMarkup(md, asset, label);
|
|
67
|
+
return buildPreviewShellMarkup(md, asset, label, options);
|
|
65
68
|
}
|
|
66
69
|
return buildDownloadLinkMarkup(md, asset, label);
|
|
67
70
|
};
|
|
@@ -107,7 +110,7 @@ export const createAgentRuntimeMarkdownRenderer = (options = {}) => {
|
|
|
107
110
|
if (asset.kind === "image") {
|
|
108
111
|
return buildImageMarkup(md, asset, alt, title);
|
|
109
112
|
}
|
|
110
|
-
return renderWorkspaceLink(md, asset, alt || asset.label);
|
|
113
|
+
return renderWorkspaceLink(md, asset, alt || asset.label, options);
|
|
111
114
|
};
|
|
112
115
|
md.core.ruler.after("inline", "agent_runtime_workspace_links", (state) => {
|
|
113
116
|
for (const blockToken of state.tokens) {
|
|
@@ -128,7 +131,7 @@ export const createAgentRuntimeMarkdownRenderer = (options = {}) => {
|
|
|
128
131
|
out.push(child);
|
|
129
132
|
continue;
|
|
130
133
|
}
|
|
131
|
-
out.push(toHtmlToken(state, renderWorkspaceLink(md, asset, next.content || asset.label)));
|
|
134
|
+
out.push(toHtmlToken(state, renderWorkspaceLink(md, asset, next.content || asset.label, options)));
|
|
132
135
|
idx += 2;
|
|
133
136
|
}
|
|
134
137
|
blockToken.children = out;
|
|
@@ -9,7 +9,12 @@ export default defineEventHandler(async (event) => {
|
|
|
9
9
|
const response = await fetch(`${cfg.baseUrl}/v1/conversations/${id}/messages`, {
|
|
10
10
|
method: "POST",
|
|
11
11
|
headers: agentRuntimeHeaders(cfg),
|
|
12
|
-
body: JSON.stringify({
|
|
12
|
+
body: JSON.stringify({
|
|
13
|
+
content: body.content,
|
|
14
|
+
context: body.context,
|
|
15
|
+
requestOptions: body.requestOptions,
|
|
16
|
+
language: body.language
|
|
17
|
+
})
|
|
13
18
|
});
|
|
14
19
|
if (!response.ok) {
|
|
15
20
|
throw createError({
|
|
@@ -6,7 +6,13 @@ export default defineEventHandler(async (event) => {
|
|
|
6
6
|
const response = await fetch(`${cfg.baseUrl}/v1/conversations`, {
|
|
7
7
|
method: "POST",
|
|
8
8
|
headers: agentRuntimeHeaders(cfg),
|
|
9
|
-
body: JSON.stringify({
|
|
9
|
+
body: JSON.stringify({
|
|
10
|
+
appId: cfg.appId,
|
|
11
|
+
env: body.env ?? {},
|
|
12
|
+
model: body.model,
|
|
13
|
+
requestOptions: body.requestOptions,
|
|
14
|
+
language: body.language
|
|
15
|
+
})
|
|
10
16
|
});
|
|
11
17
|
if (!response.ok) {
|
|
12
18
|
throw createError({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d4y/agent-runtime-nuxt",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
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
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"agent"
|
|
53
53
|
],
|
|
54
54
|
"scripts": {
|
|
55
|
-
"prepack": "nuxt-module-build build",
|
|
56
|
-
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare",
|
|
55
|
+
"prepack": "./node_modules/.bin/nuxt-module-build build",
|
|
56
|
+
"dev:prepare": "./node_modules/.bin/nuxt-module-build build --stub && ./node_modules/.bin/nuxt-module-build prepare",
|
|
57
57
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|