nknj-illustratedprimer.web.val.run
Readme

Generates a streaming illustrated primer on a subject. Enter a subject, click on titles to "delve".

🪩 To fork, sign up for Substrate to get your own API key and $50 free credits

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import inputHeader from "https://esm.town/v/substrate/inputHeader";
import { ComputeJSON, ComputeText, GenerateImage, sb, Substrate } from "npm:substrate";
import { z } from "npm:zod";
import { zodToJsonSchema } from "npm:zod-to-json-schema";
export default async function handler(req: Request): Promise<Response> {
const input = new URL(req.url).searchParams.get("input") || "modernism";
// Substrate graph
const substrate = new Substrate({ apiKey: Deno.env.get("SUBSTRATE_API_KEY_R") });
const Topic = z
.object({
concepts: z.array(z.string()).min(2).max(2).describe(
"List of advanced concepts related to a topic. Only one concept per item.",
),
})
.describe("Advanced concepts related to a topic.");
const c1 = new ComputeJSON({
prompt: `List advanced concepts related to: ${input}`,
json_schema: zodToJsonSchema(Topic),
});
const prompt1 = new ComputeText({
prompt: sb.interpolate`generate a description of an image of ${
c1.future.json_object.get("concepts").at(0)
}. Be creative depicting abstract topics using detailed abstract imagery. Include details on the background, angle & framing, and style.`,
});
const prompt2 = new ComputeText({
prompt: sb.interpolate`generate a description of an image of ${
c1.future.json_object.get("concepts").at(1)
}. Be creative depicting abstract topics using detailed abstract imagery. Include details on the background, angle & framing, and style.`,
});
const caption1 = new ComputeText({
prompt: sb.interpolate`write a short paragraph relating ${c1.future.json_object.get("concepts").at(0)} to ${input}`,
});
const caption2 = new ComputeText({
prompt: sb.interpolate`write a short paragraph relating ${
c1.future.json_object.get("concepts").at(1)
} to ${input}. It should be meaningfully different from the following content:
${caption1.future.text}`,
}, { cache_age: 800 });
const image1 = new GenerateImage({ prompt: prompt1.future.text });
const image2 = new GenerateImage({ prompt: prompt2.future.text });
const c2 = new ComputeJSON({
prompt: sb.interpolate`List advanced concepts related to: ${c1.future.json_object.get("concepts").at(0)}
They must be meaningfully different from those in this list:[${c1.future.json_object.get("concepts").at(0)}, ${
c1.future.json_object.get("concepts").at(1)
}]`,
json_schema: zodToJsonSchema(Topic),
});
const prompt3 = new ComputeText({
prompt: sb.interpolate`generate a description of an image of ${
c2.future.json_object.get("concepts").at(0)
}. Be creative depicting abstract topics using detailed abstract imagery. Include details on the background, angle & framing, and style.`,
});
const prompt4 = new ComputeText({
prompt: sb.interpolate`generate a description of an image of ${
c2.future.json_object.get("concepts").at(1)
}. Be creative depicting abstract topics using detailed abstract imagery. Include details on the background, angle & framing, and style.`,
});
const caption3 = new ComputeText({
prompt: sb.interpolate`write a short paragraph relating ${
c2.future.json_object.get("concepts").at(0)
} to ${input}. It should be meaningfully different from the following content:
${caption1.future.text}
${caption2.future.text}`,
});
const caption4 = new ComputeText({
prompt: sb.interpolate`write a short paragraph relating ${
c2.future.json_object.get("concepts").at(1)
} to ${input}. It should be meaninfully different from the following content:
${caption1.future.text}
${caption2.future.text}
${caption3.future.text}`,
});
const image3 = new GenerateImage({ prompt: prompt3.future.text });
const image4 = new GenerateImage({ prompt: prompt4.future.text });
const nodes = [image1, caption1, image2, caption2, image3, caption3, image4, caption4];
const stream = await substrate.stream(...nodes);
// UI
const capitalize = s => s.replace(/^\w/, c => c.toUpperCase());
return new Response(
new ReadableStream({
async start(controller) {
const pairs = [
{ image: null, caption: null, title: null },
{ image: null, caption: null, title: null },
{ image: null, caption: null, title: null },
{ image: null, caption: null, title: null },
];
const outputPair = (pair, index) => {
if (pair.image && pair.caption) {
controller.enqueue(new TextEncoder().encode(
`<div style="display:flex;justify-content:center;align-items:center;margin-bottom:20px;">
<div style="margin:0 10px;">${pair.image}</div>
<div style="margin:0 10px;font-size:1.2rem;">
<a href="/?input=${pair.title}"><b>${capitalize(pair.title)}</b></a><br/>${pair.caption}</div>
</div>`,
));
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
July 24, 2024