coyotte508 HF staff commited on
Commit
b8a746c
1 Parent(s): 7de539b

✨ Ability to download prompt (#176)

Browse files
src/lib/components/chat/ChatMessage.svelte CHANGED
@@ -3,10 +3,12 @@
3
  import type { Message } from "$lib/types/Message";
4
  import { afterUpdate, createEventDispatcher } from "svelte";
5
  import { deepestChild } from "$lib/utils/deepestChild";
 
6
 
7
  import CodeBlock from "../CodeBlock.svelte";
8
  import IconLoading from "../icons/IconLoading.svelte";
9
  import CarbonRotate360 from "~icons/carbon/rotate-360";
 
10
  import { PUBLIC_SEP_TOKEN } from "$lib/constants/publicSepToken";
11
  import type { Model } from "$lib/types/Model";
12
 
@@ -76,6 +78,9 @@
76
  }, 600);
77
  }
78
  });
 
 
 
79
  </script>
80
 
81
  {#if message.from === "assistant"}
@@ -112,15 +117,28 @@
112
  <div class="whitespace-break-spaces rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400">
113
  {message.content.trim()}
114
  </div>
115
- {#if !loading && message.id}
116
- <button
117
- class="absolute right-0 top-3.5 cursor-pointer rounded-lg border border-gray-100 p-1 text-xs text-gray-400 group-hover:block hover:text-gray-500 dark:border-gray-800 dark:text-gray-400 dark:hover:text-gray-300 md:hidden lg:-right-2"
118
- title="Retry"
119
- type="button"
120
- on:click={() => dispatch("retry")}
121
- >
122
- <CarbonRotate360 />
123
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  {/if}
125
  </div>
126
  {/if}
 
3
  import type { Message } from "$lib/types/Message";
4
  import { afterUpdate, createEventDispatcher } from "svelte";
5
  import { deepestChild } from "$lib/utils/deepestChild";
6
+ import { page } from "$app/stores";
7
 
8
  import CodeBlock from "../CodeBlock.svelte";
9
  import IconLoading from "../icons/IconLoading.svelte";
10
  import CarbonRotate360 from "~icons/carbon/rotate-360";
11
+ import CarbonDownload from "~icons/carbon/download";
12
  import { PUBLIC_SEP_TOKEN } from "$lib/constants/publicSepToken";
13
  import type { Model } from "$lib/types/Model";
14
 
 
78
  }, 600);
79
  }
80
  });
81
+
82
+ $: downloadLink =
83
+ message.from === "user" ? `${$page.url.pathname}/message/${message.id}/prompt` : undefined;
84
  </script>
85
 
86
  {#if message.from === "assistant"}
 
117
  <div class="whitespace-break-spaces rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400">
118
  {message.content.trim()}
119
  </div>
120
+ {#if !loading}
121
+ <div class="absolute right-0 top-3.5 flex gap-2 lg:-right-2">
122
+ {#if downloadLink}
123
+ <a
124
+ class="rounded-lg border border-gray-100 p-1 text-xs text-gray-400 group-hover:block hover:text-gray-500 dark:border-gray-800 dark:text-gray-400 dark:hover:text-gray-300 md:hidden"
125
+ title="Download prompt and parameters"
126
+ type="button"
127
+ target="_blank"
128
+ href={downloadLink}
129
+ >
130
+ <CarbonDownload />
131
+ </a>
132
+ {/if}
133
+ <button
134
+ class="cursor-pointer rounded-lg border border-gray-100 p-1 text-xs text-gray-400 group-hover:block hover:text-gray-500 dark:border-gray-800 dark:text-gray-400 dark:hover:text-gray-300 md:hidden lg:-right-2"
135
+ title="Retry"
136
+ type="button"
137
+ on:click={() => dispatch("retry")}
138
+ >
139
+ <CarbonRotate360 />
140
+ </button>
141
+ </div>
142
  {/if}
143
  </div>
144
  {/if}
src/routes/+layout.server.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { base } from "$app/paths";
2
  import { redirect } from "@sveltejs/kit";
3
  import type { LayoutServerLoad } from "./$types";
4
  import { collections } from "$lib/server/database";
@@ -7,7 +6,7 @@ import { UrlDependency } from "$lib/types/UrlDependency";
7
  import { defaultModel, models } from "$lib/server/models";
8
  import { validateModel } from "$lib/utils/models";
9
 
10
- export const load: LayoutServerLoad = async ({ locals, depends, url, request }) => {
11
  const { conversations } = collections;
12
  const urlModel = url.searchParams.get("model");
13
 
 
 
1
  import { redirect } from "@sveltejs/kit";
2
  import type { LayoutServerLoad } from "./$types";
3
  import { collections } from "$lib/server/database";
 
6
  import { defaultModel, models } from "$lib/server/models";
7
  import { validateModel } from "$lib/utils/models";
8
 
9
+ export const load: LayoutServerLoad = async ({ locals, depends, url }) => {
10
  const { conversations } = collections;
11
  const urlModel = url.searchParams.get("model");
12
 
src/routes/conversation/[id]/message/[messageId]/prompt/+server.ts ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { buildPrompt } from "$lib/buildPrompt.js";
2
+ import { collections } from "$lib/server/database";
3
+ import { models } from "$lib/server/models.js";
4
+ import { error } from "@sveltejs/kit";
5
+ import { ObjectId } from "mongodb";
6
+
7
+ export async function GET({ params, locals }) {
8
+ const convId = new ObjectId(params.id);
9
+
10
+ const conv = await collections.conversations.findOne({
11
+ _id: convId,
12
+ sessionId: locals.sessionId,
13
+ });
14
+
15
+ if (!conv) {
16
+ throw error(404, "Conversation not found");
17
+ }
18
+
19
+ const messageId = params.messageId;
20
+
21
+ const messageIndex = conv.messages.findIndex((msg) => msg.id === messageId);
22
+
23
+ if (messageIndex === -1) {
24
+ throw error(404, "Message not found");
25
+ }
26
+
27
+ const model = models.find((m) => m.name === conv.model);
28
+
29
+ if (!model) {
30
+ throw error(404, "Conversation model not found");
31
+ }
32
+
33
+ const prompt = buildPrompt(conv.messages.slice(0, messageIndex + 1), model);
34
+
35
+ return new Response(
36
+ JSON.stringify(
37
+ {
38
+ note: "This is a preview of the prompt that will be sent to the model when retrying the message. It may differ from what was sent in the past if the parameters have been updated since",
39
+ prompt,
40
+ model: model.name,
41
+ parameters: {
42
+ ...model.parameters,
43
+ return_full_text: false,
44
+ },
45
+ },
46
+ null,
47
+ 2
48
+ ),
49
+ { headers: { "Content-Type": "application/json" } }
50
+ );
51
+ }