@buildwithtrace/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/index.d.mts +171 -0
- package/dist/index.d.ts +171 -0
- package/dist/index.js +786 -0
- package/dist/index.mjs +768 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @buildwithtrace/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for [Trace](https://buildwithtrace.com) — AI-powered PCB & schematic design.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @buildwithtrace/sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Trace } from '@buildwithtrace/sdk';
|
|
11
|
+
|
|
12
|
+
const trace = new Trace({ apiKey: process.env.TRACE_API_KEY });
|
|
13
|
+
|
|
14
|
+
const sym = await trace.generateSymbol('LM7805 5V voltage regulator');
|
|
15
|
+
sym.save('./symbols/'); // writes LM7805.kicad_sym
|
|
16
|
+
|
|
17
|
+
const fp = await trace.generateFootprint('SOIC-8 3.9x4.9mm');
|
|
18
|
+
fp.save('./footprints/'); // writes SOIC-8.kicad_mod
|
|
19
|
+
|
|
20
|
+
const hits = await trace.search('3.3V LDO', { type: 'symbol' });
|
|
21
|
+
|
|
22
|
+
// Read-only Q&A:
|
|
23
|
+
const ans = await trace.ask('What ERC violations exist?', { projectDir: './my-board/' });
|
|
24
|
+
|
|
25
|
+
// Standalone agent (executes file tools locally + posts results):
|
|
26
|
+
const res = await trace.chat('Add a 100nF decoupling cap on U1', {
|
|
27
|
+
mode: 'agent',
|
|
28
|
+
projectDir: './my-board/',
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Get an API key: `buildwithtrace auth token` (CLI) or buildwithtrace.com/dashboard/settings → Developer.
|
|
33
|
+
|
|
34
|
+
## Notes
|
|
35
|
+
|
|
36
|
+
- `chat({ mode: 'agent' | 'plan' })` runs a client-side tool-execution loop for **file tools**
|
|
37
|
+
(`read_file`, `write`, `search_replace`, `list_dir`, `grep`, `delete_trace_file`) with a
|
|
38
|
+
path/extension allowlist + project-dir sandbox. **Engine tools** (ERC/DRC/gerbers/export)
|
|
39
|
+
are not yet ported — those throw `TraceToolExecutionError`; use the `buildwithtrace` CLI for them.
|
|
40
|
+
- `.trace_*` writes succeed, but the matching `.kicad_*` isn't regenerated client-side yet
|
|
41
|
+
(the converter isn't bundled in the Node SDK) — the result says so.
|
|
42
|
+
- BYOK supported via `chat(..., { llmProvider, llmApiKey, llmModelId })`.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @buildwithtrace/sdk — TypeScript SDK for Trace AI-powered EDA tools.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { Trace } from '@buildwithtrace/sdk';
|
|
7
|
+
*
|
|
8
|
+
* const trace = new Trace({ apiKey: 'your-api-key' });
|
|
9
|
+
*
|
|
10
|
+
* const symbol = await trace.generateSymbol('LM7805 5V voltage regulator');
|
|
11
|
+
* console.log(symbol.name); // "LM7805"
|
|
12
|
+
* console.log(symbol.pinCount); // 3
|
|
13
|
+
* symbol.save('./symbols/'); // writes LM7805.kicad_sym
|
|
14
|
+
*
|
|
15
|
+
* const fp = await trace.generateFootprint('SOIC-8 3.9x4.9mm');
|
|
16
|
+
* fp.save('./footprints/'); // writes SOIC-8.kicad_mod
|
|
17
|
+
*
|
|
18
|
+
* const results = await trace.search('voltage regulator', { type: 'symbol' });
|
|
19
|
+
* const answer = await trace.ask('What ERC violations exist?', { projectDir: './my-board/' });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/** Base error for SDK-surfaced backend failures (e.g. an SSE `error` event). */
|
|
23
|
+
declare class TraceError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when an agent turn requests a tool the SDK does NOT execute locally.
|
|
28
|
+
*
|
|
29
|
+
* The SDK runs a client-side tool loop for FILE tools (`read_file`, `write`,
|
|
30
|
+
* `search_replace`, `list_dir`, `grep`, `delete_trace_file`). Engine/GUI tools
|
|
31
|
+
* — ERC/DRC, gerber/drill/position export, `take_snapshot`, `run_*`, `autoroute`,
|
|
32
|
+
* etc. — are out of scope and raise this error pointing you at the
|
|
33
|
+
* `buildwithtrace` CLI or the desktop app.
|
|
34
|
+
*/
|
|
35
|
+
declare class TraceToolExecutionError extends TraceError {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
interface TraceConfig {
|
|
39
|
+
apiKey: string;
|
|
40
|
+
baseUrl?: string;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
interface GenerateResult {
|
|
44
|
+
name: string;
|
|
45
|
+
type: 'symbol' | 'footprint';
|
|
46
|
+
description: string;
|
|
47
|
+
pinCount: number;
|
|
48
|
+
padCount: number;
|
|
49
|
+
kicadSym: string | null;
|
|
50
|
+
kicadMod: string | null;
|
|
51
|
+
traceJson: Record<string, unknown> | null;
|
|
52
|
+
warning: string | null;
|
|
53
|
+
steps: Array<Record<string, unknown>>;
|
|
54
|
+
save(directory?: string): string;
|
|
55
|
+
}
|
|
56
|
+
interface SearchResult {
|
|
57
|
+
name: string;
|
|
58
|
+
library: string;
|
|
59
|
+
description: string;
|
|
60
|
+
pinCount: number;
|
|
61
|
+
padCount: number;
|
|
62
|
+
category: string;
|
|
63
|
+
source: string;
|
|
64
|
+
score: number;
|
|
65
|
+
}
|
|
66
|
+
interface TextResult {
|
|
67
|
+
text: string;
|
|
68
|
+
conversationId: string | null;
|
|
69
|
+
usage: Record<string, unknown> | null;
|
|
70
|
+
}
|
|
71
|
+
interface SearchOptions {
|
|
72
|
+
type?: 'symbol' | 'footprint';
|
|
73
|
+
limit?: number;
|
|
74
|
+
}
|
|
75
|
+
interface AskOptions {
|
|
76
|
+
projectDir?: string;
|
|
77
|
+
fileContent?: string;
|
|
78
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
79
|
+
filePath?: string;
|
|
80
|
+
conversationId?: string;
|
|
81
|
+
}
|
|
82
|
+
interface ChatOptions {
|
|
83
|
+
mode?: 'ask' | 'agent' | 'plan';
|
|
84
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
85
|
+
projectDir?: string;
|
|
86
|
+
filePath?: string;
|
|
87
|
+
fileContent?: string;
|
|
88
|
+
conversationId?: string;
|
|
89
|
+
teamId?: string;
|
|
90
|
+
attachments?: Array<Record<string, unknown>>;
|
|
91
|
+
/** BYOK: route this turn to your own provider (you pay the provider directly). */
|
|
92
|
+
llmProvider?: string;
|
|
93
|
+
llmApiKey?: string;
|
|
94
|
+
llmModelId?: string;
|
|
95
|
+
}
|
|
96
|
+
declare class Trace {
|
|
97
|
+
private apiKey;
|
|
98
|
+
private baseUrl;
|
|
99
|
+
private timeout;
|
|
100
|
+
constructor(config: TraceConfig);
|
|
101
|
+
generateSymbol(description: string, options?: {
|
|
102
|
+
datasheetUrl?: string;
|
|
103
|
+
additionalInstructions?: string;
|
|
104
|
+
}): Promise<GenerateResult>;
|
|
105
|
+
generateFootprint(description: string, options?: {
|
|
106
|
+
packageType?: string;
|
|
107
|
+
datasheetUrl?: string;
|
|
108
|
+
}): Promise<GenerateResult>;
|
|
109
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
110
|
+
ask(question: string, options?: AskOptions): Promise<TextResult>;
|
|
111
|
+
review(options?: {
|
|
112
|
+
projectDir?: string;
|
|
113
|
+
focus?: string;
|
|
114
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
115
|
+
fileContent?: string;
|
|
116
|
+
filePath?: string;
|
|
117
|
+
}): Promise<TextResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Stream a chat turn and collect the full response. Exposes the full backend
|
|
120
|
+
* chat contract: pcbnew vs eeschema (`appType`), multi-turn (`conversationId` —
|
|
121
|
+
* read it back off the result), team workspaces (`teamId`), multimodal
|
|
122
|
+
* `attachments`, `filePath` + `fileContent`, and BYOK
|
|
123
|
+
* (`llmProvider`/`llmApiKey`/`llmModelId`).
|
|
124
|
+
*
|
|
125
|
+
* NOTE: mode 'agent'/'plan' produce tool calls that run on the caller's
|
|
126
|
+
* machine. The SDK runs a client-side tool loop for FILE tools (read_file,
|
|
127
|
+
* write, search_replace, list_dir, grep, delete_trace_file), executing them
|
|
128
|
+
* under `projectDir` (defaults to process.cwd()) with the same path +
|
|
129
|
+
* extension allowlist as the CLI/desktop, and POSTing each result back to the
|
|
130
|
+
* backend so multi-step agent runs continue. Engine/GUI tools (ERC/DRC,
|
|
131
|
+
* gerber/export, take_snapshot, run_*, autoroute) are out of scope and throw
|
|
132
|
+
* TraceToolExecutionError — use the `buildwithtrace` CLI for those.
|
|
133
|
+
*/
|
|
134
|
+
chat(message: string, options?: ChatOptions): Promise<TextResult>;
|
|
135
|
+
private _post;
|
|
136
|
+
private static _httpError;
|
|
137
|
+
private _get;
|
|
138
|
+
/**
|
|
139
|
+
* Single source of truth for the /chat/stream request body. Mirrors the
|
|
140
|
+
* backend ChatRequest contract so the SDK stays in lockstep with the
|
|
141
|
+
* CLI/desktop instead of sending a stale minimal payload.
|
|
142
|
+
*/
|
|
143
|
+
private _buildChatBody;
|
|
144
|
+
/**
|
|
145
|
+
* Stream /chat/stream and drive a client-side tool loop.
|
|
146
|
+
*
|
|
147
|
+
* The backend pauses the SSE stream at each `tool_call` until the client POSTs
|
|
148
|
+
* the result to /tools/result, so we MUST read the body incrementally (not
|
|
149
|
+
* buffer it whole — that would dead-lock waiting for `done`). FILE tools are
|
|
150
|
+
* executed locally under `projectDir`; their result is posted back and the
|
|
151
|
+
* SAME stream keeps yielding events (the backend drives the multi-step loop)
|
|
152
|
+
* until `done`. Engine/GUI tools are out of scope and throw.
|
|
153
|
+
*/
|
|
154
|
+
private _streamChat;
|
|
155
|
+
private static _parseSSELine;
|
|
156
|
+
/**
|
|
157
|
+
* Execute one tool call. FILE tools run locally (sandboxed to projectDir) and
|
|
158
|
+
* their result is POSTed to /tools/result so the backend continues the stream.
|
|
159
|
+
* Engine/GUI tools are out of scope and throw TraceToolExecutionError.
|
|
160
|
+
*/
|
|
161
|
+
private _handleToolCall;
|
|
162
|
+
/**
|
|
163
|
+
* POST a tool result back to /api/<version>/tools/result (same base URL +
|
|
164
|
+
* version as /chat/stream). Non-fatal on failure — like the CLI, we warn and
|
|
165
|
+
* move on rather than crashing the loop (the backend turn will time out).
|
|
166
|
+
*/
|
|
167
|
+
private _postToolResult;
|
|
168
|
+
private _makeGenerateResult;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { type AskOptions, type ChatOptions, type GenerateResult, type SearchOptions, type SearchResult, type TextResult, Trace, type TraceConfig, TraceError, TraceToolExecutionError, Trace as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @buildwithtrace/sdk — TypeScript SDK for Trace AI-powered EDA tools.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { Trace } from '@buildwithtrace/sdk';
|
|
7
|
+
*
|
|
8
|
+
* const trace = new Trace({ apiKey: 'your-api-key' });
|
|
9
|
+
*
|
|
10
|
+
* const symbol = await trace.generateSymbol('LM7805 5V voltage regulator');
|
|
11
|
+
* console.log(symbol.name); // "LM7805"
|
|
12
|
+
* console.log(symbol.pinCount); // 3
|
|
13
|
+
* symbol.save('./symbols/'); // writes LM7805.kicad_sym
|
|
14
|
+
*
|
|
15
|
+
* const fp = await trace.generateFootprint('SOIC-8 3.9x4.9mm');
|
|
16
|
+
* fp.save('./footprints/'); // writes SOIC-8.kicad_mod
|
|
17
|
+
*
|
|
18
|
+
* const results = await trace.search('voltage regulator', { type: 'symbol' });
|
|
19
|
+
* const answer = await trace.ask('What ERC violations exist?', { projectDir: './my-board/' });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/** Base error for SDK-surfaced backend failures (e.g. an SSE `error` event). */
|
|
23
|
+
declare class TraceError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when an agent turn requests a tool the SDK does NOT execute locally.
|
|
28
|
+
*
|
|
29
|
+
* The SDK runs a client-side tool loop for FILE tools (`read_file`, `write`,
|
|
30
|
+
* `search_replace`, `list_dir`, `grep`, `delete_trace_file`). Engine/GUI tools
|
|
31
|
+
* — ERC/DRC, gerber/drill/position export, `take_snapshot`, `run_*`, `autoroute`,
|
|
32
|
+
* etc. — are out of scope and raise this error pointing you at the
|
|
33
|
+
* `buildwithtrace` CLI or the desktop app.
|
|
34
|
+
*/
|
|
35
|
+
declare class TraceToolExecutionError extends TraceError {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
interface TraceConfig {
|
|
39
|
+
apiKey: string;
|
|
40
|
+
baseUrl?: string;
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
interface GenerateResult {
|
|
44
|
+
name: string;
|
|
45
|
+
type: 'symbol' | 'footprint';
|
|
46
|
+
description: string;
|
|
47
|
+
pinCount: number;
|
|
48
|
+
padCount: number;
|
|
49
|
+
kicadSym: string | null;
|
|
50
|
+
kicadMod: string | null;
|
|
51
|
+
traceJson: Record<string, unknown> | null;
|
|
52
|
+
warning: string | null;
|
|
53
|
+
steps: Array<Record<string, unknown>>;
|
|
54
|
+
save(directory?: string): string;
|
|
55
|
+
}
|
|
56
|
+
interface SearchResult {
|
|
57
|
+
name: string;
|
|
58
|
+
library: string;
|
|
59
|
+
description: string;
|
|
60
|
+
pinCount: number;
|
|
61
|
+
padCount: number;
|
|
62
|
+
category: string;
|
|
63
|
+
source: string;
|
|
64
|
+
score: number;
|
|
65
|
+
}
|
|
66
|
+
interface TextResult {
|
|
67
|
+
text: string;
|
|
68
|
+
conversationId: string | null;
|
|
69
|
+
usage: Record<string, unknown> | null;
|
|
70
|
+
}
|
|
71
|
+
interface SearchOptions {
|
|
72
|
+
type?: 'symbol' | 'footprint';
|
|
73
|
+
limit?: number;
|
|
74
|
+
}
|
|
75
|
+
interface AskOptions {
|
|
76
|
+
projectDir?: string;
|
|
77
|
+
fileContent?: string;
|
|
78
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
79
|
+
filePath?: string;
|
|
80
|
+
conversationId?: string;
|
|
81
|
+
}
|
|
82
|
+
interface ChatOptions {
|
|
83
|
+
mode?: 'ask' | 'agent' | 'plan';
|
|
84
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
85
|
+
projectDir?: string;
|
|
86
|
+
filePath?: string;
|
|
87
|
+
fileContent?: string;
|
|
88
|
+
conversationId?: string;
|
|
89
|
+
teamId?: string;
|
|
90
|
+
attachments?: Array<Record<string, unknown>>;
|
|
91
|
+
/** BYOK: route this turn to your own provider (you pay the provider directly). */
|
|
92
|
+
llmProvider?: string;
|
|
93
|
+
llmApiKey?: string;
|
|
94
|
+
llmModelId?: string;
|
|
95
|
+
}
|
|
96
|
+
declare class Trace {
|
|
97
|
+
private apiKey;
|
|
98
|
+
private baseUrl;
|
|
99
|
+
private timeout;
|
|
100
|
+
constructor(config: TraceConfig);
|
|
101
|
+
generateSymbol(description: string, options?: {
|
|
102
|
+
datasheetUrl?: string;
|
|
103
|
+
additionalInstructions?: string;
|
|
104
|
+
}): Promise<GenerateResult>;
|
|
105
|
+
generateFootprint(description: string, options?: {
|
|
106
|
+
packageType?: string;
|
|
107
|
+
datasheetUrl?: string;
|
|
108
|
+
}): Promise<GenerateResult>;
|
|
109
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
110
|
+
ask(question: string, options?: AskOptions): Promise<TextResult>;
|
|
111
|
+
review(options?: {
|
|
112
|
+
projectDir?: string;
|
|
113
|
+
focus?: string;
|
|
114
|
+
appType?: 'eeschema' | 'pcbnew';
|
|
115
|
+
fileContent?: string;
|
|
116
|
+
filePath?: string;
|
|
117
|
+
}): Promise<TextResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Stream a chat turn and collect the full response. Exposes the full backend
|
|
120
|
+
* chat contract: pcbnew vs eeschema (`appType`), multi-turn (`conversationId` —
|
|
121
|
+
* read it back off the result), team workspaces (`teamId`), multimodal
|
|
122
|
+
* `attachments`, `filePath` + `fileContent`, and BYOK
|
|
123
|
+
* (`llmProvider`/`llmApiKey`/`llmModelId`).
|
|
124
|
+
*
|
|
125
|
+
* NOTE: mode 'agent'/'plan' produce tool calls that run on the caller's
|
|
126
|
+
* machine. The SDK runs a client-side tool loop for FILE tools (read_file,
|
|
127
|
+
* write, search_replace, list_dir, grep, delete_trace_file), executing them
|
|
128
|
+
* under `projectDir` (defaults to process.cwd()) with the same path +
|
|
129
|
+
* extension allowlist as the CLI/desktop, and POSTing each result back to the
|
|
130
|
+
* backend so multi-step agent runs continue. Engine/GUI tools (ERC/DRC,
|
|
131
|
+
* gerber/export, take_snapshot, run_*, autoroute) are out of scope and throw
|
|
132
|
+
* TraceToolExecutionError — use the `buildwithtrace` CLI for those.
|
|
133
|
+
*/
|
|
134
|
+
chat(message: string, options?: ChatOptions): Promise<TextResult>;
|
|
135
|
+
private _post;
|
|
136
|
+
private static _httpError;
|
|
137
|
+
private _get;
|
|
138
|
+
/**
|
|
139
|
+
* Single source of truth for the /chat/stream request body. Mirrors the
|
|
140
|
+
* backend ChatRequest contract so the SDK stays in lockstep with the
|
|
141
|
+
* CLI/desktop instead of sending a stale minimal payload.
|
|
142
|
+
*/
|
|
143
|
+
private _buildChatBody;
|
|
144
|
+
/**
|
|
145
|
+
* Stream /chat/stream and drive a client-side tool loop.
|
|
146
|
+
*
|
|
147
|
+
* The backend pauses the SSE stream at each `tool_call` until the client POSTs
|
|
148
|
+
* the result to /tools/result, so we MUST read the body incrementally (not
|
|
149
|
+
* buffer it whole — that would dead-lock waiting for `done`). FILE tools are
|
|
150
|
+
* executed locally under `projectDir`; their result is posted back and the
|
|
151
|
+
* SAME stream keeps yielding events (the backend drives the multi-step loop)
|
|
152
|
+
* until `done`. Engine/GUI tools are out of scope and throw.
|
|
153
|
+
*/
|
|
154
|
+
private _streamChat;
|
|
155
|
+
private static _parseSSELine;
|
|
156
|
+
/**
|
|
157
|
+
* Execute one tool call. FILE tools run locally (sandboxed to projectDir) and
|
|
158
|
+
* their result is POSTed to /tools/result so the backend continues the stream.
|
|
159
|
+
* Engine/GUI tools are out of scope and throw TraceToolExecutionError.
|
|
160
|
+
*/
|
|
161
|
+
private _handleToolCall;
|
|
162
|
+
/**
|
|
163
|
+
* POST a tool result back to /api/<version>/tools/result (same base URL +
|
|
164
|
+
* version as /chat/stream). Non-fatal on failure — like the CLI, we warn and
|
|
165
|
+
* move on rather than crashing the loop (the backend turn will time out).
|
|
166
|
+
*/
|
|
167
|
+
private _postToolResult;
|
|
168
|
+
private _makeGenerateResult;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export { type AskOptions, type ChatOptions, type GenerateResult, type SearchOptions, type SearchResult, type TextResult, Trace, type TraceConfig, TraceError, TraceToolExecutionError, Trace as default };
|