toowiredmemoriesREADME.md21 matches
1A simple Rest API that allows for you GPT to save and recall snippets of data (memories). You can read my blog post explaining it in detail here: [xkonti.tech](https://xkonti.tech/blog/giving-gpt-memory/)
23# Demonstration
7
89What GPT sent do the API:
1011```json
24# Setup
2526There are several steps to set up the API:
27- deploy and configure the API
28- create the API key for your GPT
29- add an action for the API in you GPT
30- add prompt section to your GPT so that it can use it properly
3132## Deploying the API on Val Town
3334Deploy your own memory API. You can fork the following Val to do it: https://www.val.town/v/xkonti/memoryApiExample
3536In the code configure the appropriate values:
3738- `apiName` the name of your API - used in the Privacy Policy (eg. `Memory API`)
39- `contactEmail` - the email to provide for contact in the Privacy Policy (eg. `some@email.com`)
40- `lastPolicyUpdate` - the date the Privacy Policy was last updated (eg. `2023-11-28`)
41- `blobKeyPrefix` - the prefix for the blob storage keys used by your API - more info below (eg. `gpt:memories:`)
42- `apiKeyPrefix` - the prefix for you API Keys secrets - more info below (eg. `GPTMEMORYAPI_KEY_`)
4344## Create API keys
4546The Memory API is designed to serve multiple GPTs at the same time. Each GPT should have it's own unique **name** and **API key**.
4748The **name** is used for identifying the specific GPT and appended to both:
49- `blobKeyPrefix`- to maintain separate memory storage from other GPTs
50- `apiKeyPrefix` - to maintain separate API key for each GPT
51521. Please pick a unique alphanumeric name for your GPT. For example `personaltrainer`.
532. Generate some alphanumeric API key for your GPT. For example `Wrangle-Chapped-Monkhood4-Domain-Suspend`
543. Add a new secret to your Val.town secrets storage. The Key should be the picked name prefixed by `apiKeyPrefix`. Using the default it would be `GPTMEMORYAPI_KEY_personaltrainer`. The value of the secret should be the API key itself.
5556The memories of the GPT will be stored in the blob storage under the key `blobKeyPrefix + name`, for example: `gpt:memories:personaltrainer`.
59601. Add a new action in your GPT.
612. Get the OpenAPI spefication by calling the `/openapi` endpoint of your API
623. Change all `<APIURL>` instances within the specification to the url of your deployed API. For example `https://xkonti-memoryapiexample.web.val.run`
634. Set the authentication method to basic and provide a [base64 encoded](https://www.base64encode.org/) version of the `<name>:<apiKey>`. For example: `personaltrainer:Wrangle-Chapped-Monkhood4-Domain-Suspend` -> `cGVyc29uYWx0cmFpbmVyOldyYW5nbGUtQ2hhcHBlZC1Nb25raG9vZDQtRG9tYWluLVN1c3BlbmQ=`
645. Add the link to the privacy policy, which is the `/privacy` endpoint of your API. For example: `https://xkonti-memoryapiexample.web.val.run/privacy`
6566## Adding the prompt section
86```
8788Migrated from folder: APIs/toowiredmemories
fetchNewPublicGitHubReposmain.tsx3 matches
7const order = "desc";
89const url = `https://api.github.com/search/repositories?q=${encodeURIComponent(query)}&sort=${sort}&order=${order}`;
1011const response = await fetch(url, {
12headers: {
13"Accept": "application/vnd.github.v3+json",
14"User-Agent": "Deno-GitHub-Repo-Fetcher", // GitHub API requires a user-agent header
15},
16});
1718if (!response.ok) {
19throw new Error(`GitHub API responded with status: ${response.status}`);
20}
21
honoOpenaiREADME.md1 match
3The app is set up so you can easily have a conversation between two people. The app will translate between the two selected languages, in each voice, as the speakers talk.
45Add your OpenAI API Key, and make sure to open in a separate window for Mic to work.
honoOpenaimain.tsx4 matches
67const app = new Hono();
8const openai = new OpenAI(Deno.env.get("OPENAI_API_KEY_VOICE"));
910class TranscriptionService {
19return transcription;
20} catch (error) {
21console.error("OpenAI API error:", error);
22throw error;
23}
423return c.text(translation);
424} catch (error) {
425console.error("OpenAI API error:", error);
426return c.text("Error occurred during translation", 500);
427}
450});
451} catch (error) {
452console.error("OpenAI API error:", error);
453return c.text("Error occurred during speech generation", 500);
454}
sendNotificationREADME.md1 match
1# Push Notification Sender
23This val can be used in other vals to send notifications to a segment using [OneSignal's REST API](https://documentation.onesignal.com/reference/create-notification)
45This is really handy if you want to send push notifications to your phone without building a native app! I built a barebones React PWA that asks for a password then loads the OneSignal Web SDK that I deployed to [Netlify](https://www.netlify.com/) for free. OneSignal has [easy to follow docs](https://documentation.onesignal.com/docs/web-sdk-setup) so you can build this functionality into a React, Angular, Vue app or even Wordpress! Then [install the PWA](https://www.bitcot.com/how-to-install-a-pwa-to-your-device/) on your platform of choice and you're off to the races!
sendNotificationmain.tsx1 match
6const defaultSegment = [Deno.env.get("DEFAULT_ONESIGNAL_SEGMENT")];
78const onesignalURL = "https://onesignal.com/api/v1/notifications";
910/**
4async function fetchRandomJoke() {
5const response = await fetch(
6"https://official-joke-api.appspot.com/random_joke",
7);
8return response.json();
uploadImagemain.tsx1 match
24}
25async function getUploadURL(): Promise<string> {
26const data = await (await fetch("https://www.val.town/api/trpc/generateImageUploadUrl", {
27"headers": {
28"content-type": "application/json",
sanguineAquaReptileREADME.md1 match
11[](https://www.val.town/v/stevekrouse/blob_admin_app/fork)
1213It uses [basic authentication](https://www.val.town/v/pomdtr/basicAuth) with your [Val Town API Token](https://www.val.town/settings/api) as the password (leave the username field blank).
1415# TODO
1import * as uuid from "https://deno.land/std/uuid/mod.ts";
2import { blob } from "https://esm.town/v/std/blob";
3import { getPolicy } from "https://esm.town/v/xkonti/memoryApiPolicy";
4import { Hono } from "npm:hono@3";
56export const handleMemoryApiRequest = async (
7req: Request,
8apiName: string,
9contactEmail: string,
10lastPolicyUpdate: string,
11blobKeyPrefix: string,
12apiKeyPrefix: string,
13) => {
14// ==== HELPERS ====
5152const verifyRequest = (c): { memoriesKey: string; error: any } => {
53// Verify API key coming as a Bearer header
54const authHeader = c.req.headers.get("Authorization");
55if (!authHeader || !authHeader.startsWith("Basic ")) {
67return { memoriesKey: "", error: c.text("Forbidden", 403) };
68}
69const expectedKey = Deno.env.get(apiKeyPrefix + key) ?? null;
70if (token !== expectedKey) {
71console.error("Invalid API KEY header");
72return { memoriesKey: "", error: c.text("Forbidden", 403) };
73}
75};
7677// API
7879const app = new Hono();
405// PRIVACY POLICY
406app.get("/privacy", async (c) => {
407const policy = getPolicy(apiName, contactEmail, lastPolicyUpdate);
408c.header("Content-Type", "text/html");
409return c.html(policy);
410});
411412app.get("/openapi", async (c) => {
413const specification = `
414{
415"openapi": "3.1.0",
416"info": {
417"title": "Memories and Conversations API",
418"description": "API for managing and storing long-term memories, AI conversations, and file attachments.",
419"version": "1.2.0"
420},
421"servers": [
422{
423"url": "<APIURL>"
424}
425],
434},
435"401": {
436"description": "Unauthorized - Missing or invalid API key."
437},
438"403": {
439"description": "Forbidden - Invalid API key."
440}
441},
468},
469"401": {
470"description": "Unauthorized - Missing or invalid API key."
471},
472"403": {
473"description": "Forbidden - Invalid API key."
474}
475},
524},
525"401": {
526"description": "Unauthorized - Missing or invalid API key."
527},
528"403": {
529"description": "Forbidden - Invalid API key."
530}
531},
571},
572"401": {
573"description": "Unauthorized - Missing or invalid API key."
574},
575"403": {
576"description": "Forbidden - Invalid API key."
577}
578},
602},
603"401": {
604"description": "Unauthorized - Missing or invalid API key."
605},
606"403": {
607"description": "Forbidden - Invalid API key."
608},
609"404": {
641},
642"401": {
643"description": "Unauthorized - Missing or invalid API key."
644},
645"403": {
646"description": "Forbidden - Invalid API key."
647}
648},
674},
675"401": {
676"description": "Unauthorized - Missing or invalid API key."
677},
678"403": {
679"description": "Forbidden - Invalid API key."
680},
681"404": {
728},
729"401": {
730"description": "Unauthorized - Missing or invalid API key."
731},
732"403": {
733"description": "Forbidden - Invalid API key."
734},
735"404": {
781},
782"401": {
783"description": "Unauthorized - Missing or invalid API key."
784},
785"403": {
786"description": "Forbidden - Invalid API key."
787},
788"404": {