Skip to content

Instantly share code, notes, and snippets.

@easrng
Created December 22, 2023 21:53
Show Gist options
  • Save easrng/406c5204913f6fba71a85b488a18b029 to your computer and use it in GitHub Desktop.
Save easrng/406c5204913f6fba71a85b488a18b029 to your computer and use it in GitHub Desktop.
import { lowercaseKeys } from "https://esm.town/v/stevekrouse/lowercaseKeys?v=1";
import OpenAI from "npm:openai@^4.0.0";
const openai = new OpenAI();
const input = String
.raw`Some types are fine to use from multiple threads, as long as only a single thread at a time uses a
particular value. An example here would be a ${"`"}Cell<i32>${"`"}. If two threads have a reference to a cell
at the same time, a ${"`"}&Cell<i32>${"`"}, we are in trouble --- ${"`"}Cell${"`"}'s loads and stores are not atomic
and are UB by definition if used concurrently. However, if two different threads have exclusive
access to a ${"`"}Cell${"`"}, that's fine --- because the access is exclusive, it necessary means that it is
not simultaneous. That is, it's OK for thread A to _send_ a ${"`"}Cell<i32>${"`"} to a different thread B,
as long as A itself looses access to the cell.`;
const messages = [
{
role: "system",
content: "Correct all the spelling, grammar, and punctuation mistakes in one pass.",
},
{
role: "user",
content: input,
},
];
const tools = [
{
type: "function",
function: {
name: "edit",
parameters: {
type: "object",
properties: {
edits: {
type: "array",
description: "Make multiple specific edits to the text.",
items: {
type: "object",
properties: {
before: {
type: "string",
description: "A snippet of text to replace.",
},
after: {
type: "string",
description: "The text to replace it with",
},
},
required: ["before", "after"],
},
},
},
required: ["edits"],
},
},
},
];
const response = await openai.chat.completions.create({
model: "gpt-4",
messages,
tools,
tool_choice: { type: "function", function: { name: "edit" } },
});
const { edits } = JSON.parse(response.choices[0].message.tool_calls[0].function.arguments);
let output = input;
const escapeRegex = string => string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
if (edits)
for (const r of edits) {
const replacement: any = lowercaseKeys(r);
console.log("applying " + JSON.stringify(replacement.before) + " -> " + JSON.stringify(replacement.after));
output = output.replace(
new RegExp(escapeRegex(replacement.before).replace(/\s+/g, String.raw`\s+`)),
replacement.after,
);
}
console.log("");
console.log(output);
/*
applying "it necessary means" -> "it necessarily means"
applying "looses access" -> "loses access"
Some types are fine to use from multiple threads, as long as only a single thread at a time uses a
particular value. An example here would be a `Cell<i32>`. If two threads have a reference to a cell
at the same time, a `&Cell<i32>`, we are in trouble --- `Cell`'s loads and stores are not atomic
and are UB by definition if used concurrently. However, if two different threads have exclusive
access to a `Cell`, that's fine --- because the access is exclusive, it necessarily means that it is
not simultaneous. That is, it's OK for thread A to _send_ a `Cell<i32>` to a different thread B,
as long as A itself loses access to the cell.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment