Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion lib/prompt-templates/create-local-circuit-prompt.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
fp,
getFootprintNamesByType,
getFootprintSizes,
fp,
} from "@tscircuit/footprinter"

async function fetchFileContent(url: string): Promise<string> {
Expand All @@ -19,6 +19,16 @@ async function fetchFileContent(url: string): Promise<string> {
}
}

async function fetchOptionalFileContent(url: string): Promise<string> {
try {
const response = await fetch(url)
if (!response.ok) return ""
return await response.text()
} catch {
return ""
}
}

export const createLocalCircuitPrompt = async () => {
const footprintNamesByType = getFootprintNamesByType()
const footprintSizes = getFootprintSizes()
Expand All @@ -44,11 +54,28 @@ export const createLocalCircuitPrompt = async () => {
.join("\n")
.replace(/\n\n+/g, "\n\n")

const generatedDocs = (
await fetchOptionalFileContent("https://docs.tscircuit.com/ai.txt")
).trim()
const generatedDocsSection = generatedDocs
? `
## Current auto-generated tscircuit docs

Use this generated documentation as the most current tscircuit reference. When
it conflicts with older examples in this prompt, prefer this generated docs
section.

${generatedDocs}
`
: ""

return `
You are an expert in electronic circuit design and tscircuit, and your job is to create a circuit board in tscircuit with the user-provided description.

YOU MUST ABIDE BY THE RULES IN THE RULES SECTION

${generatedDocsSection}

## tscircuit API overview

Here's an overview of the tscircuit API:
Expand Down
46 changes: 46 additions & 0 deletions tests/prompt-templates/create-local-circuit-prompt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { afterEach, expect, test } from "bun:test"
import { createLocalCircuitPrompt } from "lib/prompt-templates/create-local-circuit-prompt"

const originalFetch = globalThis.fetch

afterEach(() => {
globalThis.fetch = originalFetch
})

test("includes generated docs in the local circuit system prompt", async () => {
const requestedUrls: string[] = []

globalThis.fetch = (async (input) => {
const url = String(input)
requestedUrls.push(url)

if (url === "https://docs.tscircuit.com/ai.txt") {
return new Response('Use <chip name="U1" /> from generated docs')
}

return new Response("# Components\n<resistor />")
}) as typeof fetch

const prompt = await createLocalCircuitPrompt()

expect(requestedUrls).toContain("https://docs.tscircuit.com/ai.txt")
expect(prompt).toContain("## Current auto-generated tscircuit docs")
expect(prompt).toContain('Use <chip name="U1" /> from generated docs')
})

test("keeps prompt generation working when generated docs fetch fails", async () => {
globalThis.fetch = (async (input) => {
const url = String(input)

if (url === "https://docs.tscircuit.com/ai.txt") {
return new Response("missing", { status: 503, statusText: "Offline" })
}

return new Response("# Components\n<resistor />")
}) as typeof fetch

const prompt = await createLocalCircuitPrompt()

expect(prompt).toContain("## tscircuit API overview")
expect(prompt).not.toContain("## Current auto-generated tscircuit docs")
})
10 changes: 6 additions & 4 deletions tests/tscircuitCoder.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { createTscircuitCoder } from "lib/tscircuit-coder/tscircuitCoder"
import { expect, test } from "bun:test"
import { createTscircuitCoder } from "lib/tscircuit-coder/tscircuitCoder"
import { getPrimarySourceCodeFromVfs } from "lib/utils/get-primary-source-code-from-vfs"

test("TscircuitCoder submitPrompt streams and updates vfs", async () => {
const openAiTest = process.env.OPENAI_API_KEY ? test : test.skip

openAiTest("TscircuitCoder submitPrompt streams and updates vfs", async () => {
const streamedChunks: string[] = []
let vfsUpdated = false
const tscircuitCoder = createTscircuitCoder()
Expand All @@ -21,14 +23,14 @@ test("TscircuitCoder submitPrompt streams and updates vfs", async () => {
prompt: "add a transistor component",
})

let codeWithTransistor = getPrimarySourceCodeFromVfs(tscircuitCoder.vfs)
const codeWithTransistor = getPrimarySourceCodeFromVfs(tscircuitCoder.vfs)
expect(codeWithTransistor).toInclude("transistor")

await tscircuitCoder.submitPrompt({
prompt: "add a tssop20 chip",
})

let codeWithChip = getPrimarySourceCodeFromVfs(tscircuitCoder.vfs)
const codeWithChip = getPrimarySourceCodeFromVfs(tscircuitCoder.vfs)
expect(codeWithChip).toInclude("tssop20")
expect(codeWithChip).toInclude("transistor")

Expand Down
6 changes: 4 additions & 2 deletions tests/utils/generate-random-prompts.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { describe, it, expect } from "bun:test"
import { describe, expect, it } from "bun:test"
import { generateRandomPrompts } from "../../lib/utils/generate-random-prompts"

const openAiIt = process.env.OPENAI_API_KEY ? it : it.skip

describe("generateRandomPrompts", () => {
it("should return an array of prompts", async () => {
openAiIt("should return an array of prompts", async () => {
const prompts = await generateRandomPrompts(3)

expect(Array.isArray(prompts)).toBe(true)
Expand Down
Loading