Avatar

@yawnxyz

7 public vals
Joined March 31, 2023
i make ui for ai
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
/** @jsxImportSource npm:hono@3/jsx */
import { fetchText } from "https://esm.town/v/stevekrouse/fetchText";
import { chat } from "https://esm.town/v/stevekrouse/openai";
import cronstrue from "npm:cronstrue";
import { Hono } from "npm:hono@3";
const examples = [
{
user: "website that shows the current time",
content: `/** @jsxImportSource npm:react */
export default function() {
return <h1>{new Date().toLocaleTimeString()}</h1>;
}`,
},
{
user: `A collaborative poem builder.
It stores each line of the poem in sqlite.
It has a textbox that lets anyone input a new line to the poem.`,
content: await fetchText("https://esm.town/v/stevekrouse/poembuilder3?v=4"),
},
{
user: "an app that uses chatgpt to convert natural language to cron syntax",
content: await fetchText("https://esm.town/v/stevekrouse/cron2"),
},
];
const app = new Hono();
export default app.fetch;
app.get("/", async (c) => {
const example = examples[0] // examples[Math.floor(Math.random() * examples.length)];
const description = c.req.query("description") || example.user;
let code = c.req.query("description") ? await compile(description) : example.content;
return c.html(
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com" />
<title>Val Writer</title>
</head>
<body class="flex p-6 flex-col space-y-4 max-w-2xl mx-auto">
<div>
<h1 class="text-3xl">Val Writer</h1>
<p>Compile your prompt into code</p>
</div>
<form class="flex space-x-2" hx-disabled-elt="button">
<textarea
name="description"
required
class="w-full border-2 rounded-lg p-2"
rows={5}
>
{description}
</textarea>
<button class="bg-purple-500 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded disabled:hidden">
Write
</button>
</form>
<div>
<pre>
{code}
</pre>
</div>
</body>
</html>,
);
});
export async function compile(description: string) {
const messages = [
{
role: "system",
content: `You are an expert fullstack developer.
You convert user requests to code.
You write Deno TypeScript.
Reply ONLY with valid Typescript.
Export the fetch function to run the server.
Only use web standard fetch. Export the fetch function to start the server.
Add extensive comments`,
},
...examples.flatMap((example) => [, {
role: "user",
content: example.user,
}, {
role: "assistant",
content: example.content,
}]),
{ role: "user", content: description },
];
const { content } = await chat(messages, {
model: "gpt-4-turbo-2024-04-09",
max_tokens: 4000,
});
return content;
}

markdown.download

Handy microservice/library to convert various data sources into markdown. Intended to make it easier to consume the web in ereaders

https://jsr.io/@tarasglek/markdown-download

Features

  • Apply readability
  • Further convert article into markdown to simplify it
  • Allow webpages to be viewable as markdown via curl
  • Serve markdown converted to html to browsers
  • Extract youtube subtitles

Source

https://github.com/tarasglek/markdown-download

https://www.val.town/v/taras/markdown_download

License: MIT

Usage: https://markdown.download/ + URL

Dev: https://val.markdown.download/ + URL

Readme
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 { isProbablyReaderable, Readability } from "npm:@mozilla/readability@^0.5.0";
import { DOMParser } from "npm:linkedom@0.16.10";
import { marked } from "npm:marked@12.0.1";
import { getSubtitles } from "npm:youtube-captions-scraper@^2.0.1";
const isCloudflareWorker = typeof Request !== "undefined" && typeof Response !== "undefined";
// init async loading of modules
const AgentMarkdownImport = isCloudflareWorker ? import("npm:agentmarkdown@6.0.0") : null;
const TurndownService = isCloudflareWorker ? null : await import("npm:turndown@^7.1.3");
async function markdown2html(html: string): Promise<string> {
if (AgentMarkdownImport) {
// TurndownService doesn't work on cf
// Dynamically import AgentMarkdown when running in Cloudflare Worker
const { AgentMarkdown } = await AgentMarkdownImport;
return await AgentMarkdown.produce(html);
} else {
// Dynamically import TurndownService otherwise
return new (await TurndownService)().turndown(html);
}
}
function getYoutubeVideoID(url: URL): string | null {
const regExp = /(?:youtube\.com\/(?:[^/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?/\s]{11})/i;
const match = url.href.match(regExp);
return match ? match[1] : null;
}
function response(message: string, contentType = "text/markdown"): Response {
const headers = new Headers();
headers.set("Access-Control-Allow-Origin", "*");
headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
headers.set("Access-Control-Max-Age", "86400");
headers.set("Content-Type", contentType);
return new Response(message, {
status: 200,
headers: headers,
});
}
function err(msg: string): Response {
const errorMessage = JSON.stringify({
error: {
message: msg,
code: 400,
},
});
return response(errorMessage, "application/json");
}
function fudgeURL(url: string) {
try {
return new URL(url);
} catch (e) {
// console.log("Url parsing failed", e.stack);
return new URL("https://" + url);
}
}
function processInput(req: Request) {
let ret = {
url: undefined as undefined | URL,
response: undefined as undefined | Response,
};
const myurl = new URL(req.url);
let pathname = myurl.pathname.substring(1) + myurl.search;
if (!pathname.startsWith("http")) {
const urlAsFormParam = myurl.searchParams.get("url");
if (urlAsFormParam) {
pathname = urlAsFormParam;
} else if (pathname.length < 2) {
ret.response = response(
generate_ui(
"URL to convert to markdown:",
"https://www.val.town/v/taras/markdown_download",
"markdown.download",
),
"text/html",
);
return ret;
}
}
ret.url = fudgeURL(pathname);
return ret;
}
export default async function(req: Request): Promise<Response> {
const action = processInput(req);
const url = action.url;
if (!url) {
return action.response!;
}
const youtubeVideoID = getYoutubeVideoID(url);
if (youtubeVideoID) {
const arr = (await getSubtitles({
videoID: youtubeVideoID,
})) as { text: string }[];
const description = "## Generated Transcription\n\n"
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
import { fetch } from "https://esm.town/v/std/fetch";
export async function openaiUploadFile({ key, data, purpose = "assistants" }: {
key: string;
data: any;
purpose: string;
}) {
let file = data instanceof File || data instanceof Blob
? data
: typeof data === "string"
? new Blob([data])
: Array.isArray(data)
? new Blob([data.map((d) => JSON.stringify(d)).join("\n")])
: new Blob([JSON.stringify(data)]);
let formData = new FormData();
formData.append("purpose", purpose);
formData.append("file", file, "data.json");
let result = await fetch("https://api.openai.com/v1/files", {
method: "POST",
headers: {
"authorization": `Bearer ${key}`,
},
body: formData,
}).then((r) => r.json());
if (result.error)
throw new Error("OpenAI Upload Error: " + result.error.message);
else
return result;
}
1
2
3
export default async function what() {
console.log("what");
}
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
import { fetch } from "https://esm.town/v/std/fetch";
export async function openaiUploadFile({ key, data, filename = "data.json", purpose = "assistants" }: {
key: string;
data: any;
filename: string;
purpose: string;
}) {
let file = data instanceof File || data instanceof Blob
? data
: typeof data === "string"
? new Blob([data])
: Array.isArray(data)
? new Blob([data.map((d) => JSON.stringify(d)).join("\n")])
: new Blob([JSON.stringify(data)]);
let formData = new FormData();
formData.append("purpose", purpose);
formData.append("file", file, filename);
let result = await fetch("https://api.openai.com/v1/files", {
method: "POST",
headers: {
"authorization": `Bearer ${key}`,
},
body: formData,
}).then((r) => r.json());
if (result.error)
throw new Error("OpenAI Upload Error: " + result.error.message);
else
return result;
}
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
import { OpenAI } from "https://esm.town/v/std/openai?v=2";
const openai = new OpenAI();
const functionExpression = await openai.chat.completions.create({
"messages": [
{ "role": "user", "content": "whats the weather in sf" },
],
tools: [
{
function: {
name: "weather",
parameters: {
"type": "object",
"properties": {
"location": { "type": "string", "description": "The city and state e.g. San Francisco, CA" },
"unit": { "type": "string", "enum": ["c", "f"] },
},
"required": ["location"],
},
},
type: "function",
},
],
model: "gpt-4",
max_tokens: 30,
});
console.log(functionExpression.choices);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export let test = (req, res) => {
res.json({
schema_version: "v1",
name_for_human: "APIs.guru Plugin",
name_for_model: "apis.guru",
description_for_human: "Plugin for accessing APIs.guru OpenAPI Directory.",
description_for_model:
"Plugin for accessing APIs.guru OpenAPI Directory. Use the list.json endpoint to find APIs. Use the metrics.json endpoint to find metadata about APIs such as counts, totals and charting data.",
auth: {
type: "none",
},
api: {
type: "openapi",
url: "https://api.apis.guru/v2/ai-openapi.yaml",
is_user_authenticated: false,
},
logo_url: "https://api.apis.guru/logo.svg",
contact_email: "mike.ralphson@gmail.com",
legal_info_url: "https://apis.guru",
});
};
Next