@factory/droid-sdk 0.3.0 → 0.5.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.
@@ -6,12 +6,13 @@
6
6
  npm install @factory/droid-sdk
7
7
  ```
8
8
 
9
- Requires Node.js 18+ and the `droid` CLI on your PATH.
9
+ Requires Node.js 18+ and the `droid` CLI on your PATH. This guide covers **exec mode** (`run()`, `createSession()`), which spawns a subprocess per session. For WebSocket-based daemon mode with concurrent sessions, see the [Daemon Usage Guide](./daemon-usage-guide.md).
10
10
 
11
11
  ```ts
12
12
  import { run } from '@factory/droid-sdk';
13
13
 
14
14
  const result = await run('What files are in this directory?', {
15
+ apiKey: process.env.FACTORY_API_KEY!,
15
16
  cwd: process.cwd(),
16
17
  });
17
18
  console.log(result.text);
@@ -26,7 +27,10 @@ Send a prompt, get a result, done. The session is created and closed automatical
26
27
  ```ts
27
28
  import { run } from '@factory/droid-sdk';
28
29
 
29
- const result = await run('What is 2 + 2?', { cwd: process.cwd() });
30
+ const result = await run('What is 2 + 2?', {
31
+ apiKey: process.env.FACTORY_API_KEY!,
32
+ cwd: process.cwd(),
33
+ });
30
34
  console.log(result.text);
31
35
  ```
32
36
 
@@ -38,6 +42,7 @@ Force the response to match a JSON schema. The validated object is available on
38
42
  import { OutputFormatType, run } from '@factory/droid-sdk';
39
43
 
40
44
  const result = await run('Pick a number between 1 and 42.', {
45
+ apiKey: process.env.FACTORY_API_KEY!,
41
46
  cwd: process.cwd(),
42
47
  outputFormat: {
43
48
  type: OutputFormatType.JsonSchema,
@@ -57,16 +62,19 @@ console.log((result.structuredOutput as { number: number }).number);
57
62
  Create a session once, then call `stream()` multiple times. Context is preserved across turns.
58
63
 
59
64
  ```ts
60
- import { createSession } from '@factory/droid-sdk';
65
+ import { createSession, DroidMessageType } from '@factory/droid-sdk';
61
66
 
62
- const session = await createSession({ cwd: process.cwd() });
67
+ const session = await createSession({
68
+ apiKey: process.env.FACTORY_API_KEY!,
69
+ cwd: process.cwd(),
70
+ });
63
71
 
64
72
  for await (const msg of session.stream('Remember the word "mango".')) {
65
73
  // consume first turn
66
74
  }
67
75
 
68
76
  for await (const msg of session.stream('What word did I say?')) {
69
- if (msg.type === 'assistant') console.log(msg.text);
77
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
70
78
  }
71
79
 
72
80
  await session.close();
@@ -77,12 +85,14 @@ await session.close();
77
85
  Reconnect to a previously created session by its ID.
78
86
 
79
87
  ```ts
80
- import { resumeSession } from '@factory/droid-sdk';
88
+ import { resumeSession, DroidMessageType } from '@factory/droid-sdk';
81
89
 
82
- const session = await resumeSession('existing-session-id');
90
+ const session = await resumeSession('existing-session-id', {
91
+ apiKey: process.env.FACTORY_API_KEY!,
92
+ });
83
93
 
84
94
  for await (const msg of session.stream('Continue where we left off.')) {
85
- if (msg.type === 'assistant') console.log(msg.text);
95
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
86
96
  }
87
97
 
88
98
  await session.close();
@@ -95,7 +105,10 @@ await session.close();
95
105
  ```ts
96
106
  import { createSession, DroidMessageType } from '@factory/droid-sdk';
97
107
 
98
- const session = await createSession({ cwd: process.cwd() });
108
+ const session = await createSession({
109
+ apiKey: process.env.FACTORY_API_KEY!,
110
+ cwd: process.cwd(),
111
+ });
99
112
 
100
113
  for await (const msg of session.stream(
101
114
  'List files in the current directory.'
@@ -126,7 +139,10 @@ Enable `includePartialMessages` to get token-by-token deltas, thinking blocks, a
126
139
  ```ts
127
140
  import { createSession, DroidMessageType } from '@factory/droid-sdk';
128
141
 
129
- const session = await createSession({ cwd: process.cwd() });
142
+ const session = await createSession({
143
+ apiKey: process.env.FACTORY_API_KEY!,
144
+ cwd: process.cwd(),
145
+ });
130
146
 
131
147
  for await (const msg of session.stream('Explain recursion.', {
132
148
  includePartialMessages: true,
@@ -144,19 +160,25 @@ await session.close();
144
160
  Use `session.interrupt()` to stop the current turn server-side, or pass an `AbortSignal` to cancel from the client.
145
161
 
146
162
  ```ts
147
- import { createSession } from '@factory/droid-sdk';
163
+ import { createSession, DroidMessageType } from '@factory/droid-sdk';
148
164
 
149
165
  // Interrupt after receiving some output
150
- const session = await createSession({ cwd: process.cwd() });
166
+ const session = await createSession({
167
+ apiKey: process.env.FACTORY_API_KEY!,
168
+ cwd: process.cwd(),
169
+ });
151
170
  for await (const msg of session.stream('Write a long essay.')) {
152
- if (msg.type === 'assistant') {
171
+ if (msg.type === DroidMessageType.Assistant) {
153
172
  await session.interrupt();
154
173
  }
155
174
  }
156
175
  await session.close();
157
176
 
158
177
  // Or cancel with AbortSignal
159
- const session2 = await createSession({ cwd: process.cwd() });
178
+ const session2 = await createSession({
179
+ apiKey: process.env.FACTORY_API_KEY!,
180
+ cwd: process.cwd(),
181
+ });
160
182
  const controller = new AbortController();
161
183
  setTimeout(() => controller.abort(), 2000);
162
184
 
@@ -179,6 +201,7 @@ Define custom tools that Droid can call during a session. Tools are served via a
179
201
  import {
180
202
  createSession,
181
203
  createSdkMcpServer,
204
+ DroidMessageType,
182
205
  tool,
183
206
  ToolConfirmationOutcome,
184
207
  } from '@factory/droid-sdk';
@@ -199,13 +222,14 @@ const server = createSdkMcpServer({
199
222
  });
200
223
 
201
224
  const session = await createSession({
225
+ apiKey: process.env.FACTORY_API_KEY!,
202
226
  cwd: process.cwd(),
203
227
  mcpServers: [server],
204
228
  permissionHandler: () => ToolConfirmationOutcome.ProceedOnce,
205
229
  });
206
230
 
207
231
  for await (const msg of session.stream('Look up Alice.')) {
208
- if (msg.type === 'assistant') console.log(msg.text);
232
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
209
233
  }
210
234
 
211
235
  await session.close();
@@ -219,6 +243,7 @@ Control what Droid can do without asking for permission. Set at session creation
219
243
  import { createSession, AutonomyLevel } from '@factory/droid-sdk';
220
244
 
221
245
  const session = await createSession({
246
+ apiKey: process.env.FACTORY_API_KEY!,
222
247
  cwd: process.cwd(),
223
248
  autonomyLevel: AutonomyLevel.High, // Off | Low | Medium | High
224
249
  });
@@ -236,6 +261,7 @@ Restrict which tools Droid can use. Accepts tool IDs like `'Read'`, `'Execute'`,
236
261
  import { createSession } from '@factory/droid-sdk';
237
262
 
238
263
  const session = await createSession({
264
+ apiKey: process.env.FACTORY_API_KEY!,
239
265
  cwd: process.cwd(),
240
266
  enabledToolIds: ['Read', 'Grep'],
241
267
  disabledToolIds: ['Execute'],
@@ -258,6 +284,7 @@ import {
258
284
  } from '@factory/droid-sdk';
259
285
 
260
286
  await run('Create hello.txt with "Hello, World!"', {
287
+ apiKey: process.env.FACTORY_API_KEY!,
261
288
  cwd: process.cwd(),
262
289
  permissionHandler(params) {
263
290
  const safe = params.toolUses.every(
@@ -283,6 +310,7 @@ import {
283
310
  } from '@factory/droid-sdk';
284
311
 
285
312
  const session = await createSession({
313
+ apiKey: process.env.FACTORY_API_KEY!,
286
314
  cwd: process.cwd(),
287
315
  interactionMode: DroidInteractionMode.Spec,
288
316
  permissionHandler(params) {
@@ -306,9 +334,12 @@ Send images or documents alongside your prompt. Images must be base64-encoded.
306
334
 
307
335
  ```ts
308
336
  import { readFileSync } from 'node:fs';
309
- import { createSession } from '@factory/droid-sdk';
337
+ import { createSession, DroidMessageType } from '@factory/droid-sdk';
310
338
 
311
- const session = await createSession({ cwd: process.cwd() });
339
+ const session = await createSession({
340
+ apiKey: process.env.FACTORY_API_KEY!,
341
+ cwd: process.cwd(),
342
+ });
312
343
 
313
344
  for await (const msg of session.stream('Describe this image.', {
314
345
  images: [
@@ -319,7 +350,7 @@ for await (const msg of session.stream('Describe this image.', {
319
350
  },
320
351
  ],
321
352
  })) {
322
- if (msg.type === 'assistant') console.log(msg.text);
353
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
323
354
  }
324
355
 
325
356
  await session.close();
@@ -330,17 +361,26 @@ await session.close();
330
361
  Create a copy of the current session with all context preserved. Useful for branching a conversation.
331
362
 
332
363
  ```ts
333
- import { createSession, resumeSession } from '@factory/droid-sdk';
364
+ import {
365
+ createSession,
366
+ DroidMessageType,
367
+ resumeSession,
368
+ } from '@factory/droid-sdk';
334
369
 
335
- const session = await createSession({ cwd: process.cwd() });
370
+ const session = await createSession({
371
+ apiKey: process.env.FACTORY_API_KEY!,
372
+ cwd: process.cwd(),
373
+ });
336
374
  for await (const msg of session.stream('Remember: the password is "banana".')) {
337
375
  }
338
376
 
339
377
  const { newSessionId } = await session.forkSession();
340
- const fork = await resumeSession(newSessionId);
378
+ const fork = await resumeSession(newSessionId, {
379
+ apiKey: process.env.FACTORY_API_KEY!,
380
+ });
341
381
 
342
382
  for await (const msg of fork.stream('What is the password?')) {
343
- if (msg.type === 'assistant') console.log(msg.text);
383
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
344
384
  }
345
385
 
346
386
  await fork.close();
@@ -354,7 +394,10 @@ Summarize and remove old messages to free up context window space.
354
394
  ```ts
355
395
  import { createSession } from '@factory/droid-sdk';
356
396
 
357
- const session = await createSession({ cwd: process.cwd() });
397
+ const session = await createSession({
398
+ apiKey: process.env.FACTORY_API_KEY!,
399
+ cwd: process.cwd(),
400
+ });
358
401
 
359
402
  // ... after many turns ...
360
403
  const result = await session.compactSession();
@@ -376,7 +419,10 @@ import {
376
419
  AutonomyLevel,
377
420
  } from '@factory/droid-sdk';
378
421
 
379
- const transport = new ProcessTransport({ cwd: process.cwd() });
422
+ const transport = new ProcessTransport({
423
+ cwd: process.cwd(),
424
+ env: { FACTORY_API_KEY: process.env.FACTORY_API_KEY! },
425
+ });
380
426
  await transport.connect();
381
427
  const client = new DroidClient({ transport });
382
428
 
@@ -423,6 +469,7 @@ Choose which model to use and how much reasoning effort to apply. Configurable a
423
469
  import { createSession, ReasoningEffort } from '@factory/droid-sdk';
424
470
 
425
471
  const session = await createSession({
472
+ apiKey: process.env.FACTORY_API_KEY!,
426
473
  cwd: process.cwd(),
427
474
  modelId: 'claude-sonnet-4-20250514',
428
475
  reasoningEffort: ReasoningEffort.High,
@@ -443,7 +490,10 @@ Observe file hooks (pre/post tool execution hooks) as they run during a session.
443
490
  ```ts
444
491
  import { createSession, DroidMessageType } from '@factory/droid-sdk';
445
492
 
446
- const session = await createSession({ cwd: process.cwd() });
493
+ const session = await createSession({
494
+ apiKey: process.env.FACTORY_API_KEY!,
495
+ cwd: process.cwd(),
496
+ });
447
497
 
448
498
  for await (const msg of session.stream('Create a new file.')) {
449
499
  if (msg.type === DroidMessageType.Hook) {
@@ -463,9 +513,10 @@ await session.close();
463
513
  Programmatically answer questions that Droid asks the user during execution.
464
514
 
465
515
  ```ts
466
- import { createSession } from '@factory/droid-sdk';
516
+ import { createSession, DroidMessageType } from '@factory/droid-sdk';
467
517
 
468
518
  const session = await createSession({
519
+ apiKey: process.env.FACTORY_API_KEY!,
469
520
  cwd: process.cwd(),
470
521
  askUserHandler(params) {
471
522
  return {
@@ -480,7 +531,7 @@ const session = await createSession({
480
531
  });
481
532
 
482
533
  for await (const msg of session.stream('Help me set up this project.')) {
483
- if (msg.type === 'assistant') console.log(msg.text);
534
+ if (msg.type === DroidMessageType.Assistant) console.log(msg.text);
484
535
  }
485
536
 
486
537
  await session.close();
@@ -493,7 +544,10 @@ Add, remove, toggle, and list MCP servers at runtime within an active session.
493
544
  ```ts
494
545
  import { createSession, McpServerType } from '@factory/droid-sdk';
495
546
 
496
- const session = await createSession({ cwd: process.cwd() });
547
+ const session = await createSession({
548
+ apiKey: process.env.FACTORY_API_KEY!,
549
+ cwd: process.cwd(),
550
+ });
497
551
 
498
552
  await session.addMcpServer({
499
553
  name: 'my-server',
@@ -514,7 +568,10 @@ Query current context window usage to understand how much capacity remains.
514
568
  ```ts
515
569
  import { createSession } from '@factory/droid-sdk';
516
570
 
517
- const session = await createSession({ cwd: process.cwd() });
571
+ const session = await createSession({
572
+ apiKey: process.env.FACTORY_API_KEY!,
573
+ cwd: process.cwd(),
574
+ });
518
575
  for await (const msg of session.stream('Hello')) {
519
576
  }
520
577
 
@@ -533,7 +590,10 @@ Monitor token consumption in real-time via stream events, or read the final tota
533
590
  ```ts
534
591
  import { createSession, DroidMessageType } from '@factory/droid-sdk';
535
592
 
536
- const session = await createSession({ cwd: process.cwd() });
593
+ const session = await createSession({
594
+ apiKey: process.env.FACTORY_API_KEY!,
595
+ cwd: process.cwd(),
596
+ });
537
597
 
538
598
  for await (const msg of session.stream('Summarize this project.', {
539
599
  includePartialMessages: true,
@@ -558,7 +618,10 @@ List all available skills in the current session.
558
618
  ```ts
559
619
  import { createSession } from '@factory/droid-sdk';
560
620
 
561
- const session = await createSession({ cwd: process.cwd() });
621
+ const session = await createSession({
622
+ apiKey: process.env.FACTORY_API_KEY!,
623
+ cwd: process.cwd(),
624
+ });
562
625
  const { skills } = await session.listSkills();
563
626
 
564
627
  for (const skill of skills) {
@@ -575,7 +638,10 @@ Subscribe to raw protocol notifications for custom event handling beyond the str
575
638
  ```ts
576
639
  import { createSession, SessionNotificationType } from '@factory/droid-sdk';
577
640
 
578
- const session = await createSession({ cwd: process.cwd() });
641
+ const session = await createSession({
642
+ apiKey: process.env.FACTORY_API_KEY!,
643
+ cwd: process.cwd(),
644
+ });
579
645
 
580
646
  const unsubscribe = session.onNotification(
581
647
  (notification) => {
@@ -604,7 +670,9 @@ import {
604
670
  } from '@factory/droid-sdk';
605
671
 
606
672
  try {
607
- const session = await resumeSession('nonexistent-id');
673
+ const session = await resumeSession('nonexistent-id', {
674
+ apiKey: process.env.FACTORY_API_KEY!,
675
+ });
608
676
  } catch (error) {
609
677
  if (error instanceof SessionNotFoundError) {
610
678
  console.log(`Session not found: ${error.sessionId}`);
@@ -634,6 +702,7 @@ The package also exports its full Zod schema surface from `src/schemas/index.ts`
634
702
 
635
703
  | Field | Type | Description |
636
704
  | :------------------------ | :----------------------- | :---------------------------------------------------------- |
705
+ | `apiKey` | `string` | **Required.** Factory API key for authentication |
637
706
  | `cwd` | `string` | Working directory for the session |
638
707
  | `machineId` | `string` | Machine identifier for initialization |
639
708
  | `modelId` | `string` | LLM model identifier |
@@ -646,6 +715,7 @@ The package also exports its full Zod schema surface from `src/schemas/index.ts`
646
715
  | `enabledToolIds` | `string[]` | Tool allowlist |
647
716
  | `disabledToolIds` | `string[]` | Tool denylist |
648
717
  | `tags` | `SessionTag[]` | Session tags for categorization |
718
+ | `sessionSource` | `SessionSource` | Attribution metadata (e.g., integration origin) |
649
719
  | `permissionHandler` | `PermissionHandler` | Tool confirmation callback |
650
720
  | `askUserHandler` | `AskUserHandler` | Structured user-input callback |
651
721
  | `execPath` | `string` | Path to `droid` executable (default: `"droid"`) |
@@ -7,7 +7,10 @@
7
7
 
8
8
  import { createSession } from '@factory/droid-sdk';
9
9
 
10
- const session = await createSession({ cwd: process.cwd() });
10
+ const session = await createSession({
11
+ apiKey: process.env.FACTORY_API_KEY!,
12
+ cwd: process.cwd(),
13
+ });
11
14
  const controller = new AbortController();
12
15
  const timeout = setTimeout(
13
16
  () => controller.abort(new Error('Stopped by AbortController')),
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Manual smoke test for the daemon SDK — multiple concurrent sessions.
3
+ *
4
+ * Spawns a local daemon, creates two sessions in separate /tmp directories,
5
+ * and runs them concurrently over a single WebSocket connection.
6
+ *
7
+ * Usage:
8
+ * npx tsx examples/daemon-multi-session.ts
9
+ */
10
+
11
+ import { connectDaemon, DroidMessageType } from '@factory/droid-sdk';
12
+
13
+ async function main(): Promise<void> {
14
+ console.log('Connecting to local daemon...\n');
15
+ const daemon = await connectDaemon({ apiKey: process.env.FACTORY_API_KEY! });
16
+ console.log('Connected!\n');
17
+
18
+ const frontend = await daemon.createSession({
19
+ cwd: '/tmp/daemon-test-frontend',
20
+ });
21
+ const backend = await daemon.createSession({
22
+ cwd: '/tmp/daemon-test-backend',
23
+ });
24
+
25
+ console.log('Two sessions created. Running concurrently...\n');
26
+
27
+ await Promise.all([
28
+ (async () => {
29
+ for await (const msg of frontend.stream(
30
+ 'Create a file called hello.md with a short greeting message. Just a few lines.'
31
+ )) {
32
+ if (msg.type === DroidMessageType.Assistant) {
33
+ process.stdout.write(`[frontend] ${msg.text}\n`);
34
+ } else if (msg.type === DroidMessageType.ToolCall) {
35
+ console.log(`[frontend] [tool] ${msg.toolUse.name}`);
36
+ } else if (msg.type === DroidMessageType.Result) {
37
+ console.log(`[frontend] Done in ${msg.durationMs}ms`);
38
+ }
39
+ }
40
+ await frontend.close();
41
+ })(),
42
+ (async () => {
43
+ for await (const msg of backend.stream(
44
+ 'Create a file called notes.md with 3 random fun facts. Keep it short.'
45
+ )) {
46
+ if (msg.type === DroidMessageType.Assistant) {
47
+ process.stdout.write(`[backend] ${msg.text}\n`);
48
+ } else if (msg.type === DroidMessageType.ToolCall) {
49
+ console.log(`[backend] [tool] ${msg.toolUse.name}`);
50
+ } else if (msg.type === DroidMessageType.Result) {
51
+ console.log(`[backend] Done in ${msg.durationMs}ms`);
52
+ }
53
+ }
54
+ await backend.close();
55
+ })(),
56
+ ]);
57
+
58
+ await daemon.close();
59
+ console.log(
60
+ '\nDone. Check /tmp/daemon-test-frontend/hello.md and /tmp/daemon-test-backend/notes.md'
61
+ );
62
+ }
63
+
64
+ main().catch((err: unknown) => {
65
+ console.error('Error:', err);
66
+ process.exit(1);
67
+ });
@@ -25,6 +25,7 @@ async function main(): Promise<void> {
25
25
  'Return only valid JSON and do not include markdown fences.',
26
26
  ].join(' '),
27
27
  {
28
+ apiKey: process.env.FACTORY_API_KEY!,
28
29
  execPath,
29
30
  cwd: process.cwd(),
30
31
  }
@@ -21,7 +21,9 @@ async function streamText(
21
21
  prompt: string
22
22
  ): Promise<string> {
23
23
  let text = '';
24
- for await (const msg of session.stream(prompt)) {
24
+ for await (const msg of session.stream(prompt, {
25
+ includePartialMessages: true,
26
+ })) {
25
27
  if (msg.type === DroidMessageType.AssistantTextDelta) {
26
28
  text += msg.text;
27
29
  }
@@ -30,7 +32,10 @@ async function streamText(
30
32
  }
31
33
 
32
34
  async function main(): Promise<void> {
33
- const session = await createSession({ cwd: process.cwd() });
35
+ const session = await createSession({
36
+ apiKey: process.env.FACTORY_API_KEY!,
37
+ cwd: process.cwd(),
38
+ });
34
39
  let fork: Awaited<ReturnType<typeof resumeSession>> | null = null;
35
40
 
36
41
  try {
@@ -40,7 +45,9 @@ async function main(): Promise<void> {
40
45
  const { newSessionId } = await session.forkSession();
41
46
  console.log(`Forked session: ${newSessionId}\n`);
42
47
 
43
- fork = await resumeSession(newSessionId);
48
+ fork = await resumeSession(newSessionId, {
49
+ apiKey: process.env.FACTORY_API_KEY!,
50
+ });
44
51
 
45
52
  const result = await streamText(
46
53
  fork,
@@ -15,7 +15,13 @@ async function main(): Promise<void> {
15
15
  console.log(`Sending prompt: "${prompt}"\n`);
16
16
 
17
17
  // Note: To actually see hooks, you need to have hooks configured in your droid settings.
18
- const session = await createSession({ cwd: process.cwd() });
18
+ const apiKey = process.env.FACTORY_API_KEY;
19
+ if (!apiKey) {
20
+ console.error('Set FACTORY_API_KEY environment variable.');
21
+ process.exit(1);
22
+ }
23
+
24
+ const session = await createSession({ apiKey, cwd: process.cwd() });
19
25
 
20
26
  try {
21
27
  for await (const msg of session.stream(prompt)) {
@@ -7,8 +7,13 @@
7
7
 
8
8
  import { createSession, resumeSession } from '@factory/droid-sdk';
9
9
 
10
- const session = await createSession({ cwd: process.cwd() });
11
- const resumed = await resumeSession(session.sessionId);
10
+ const session = await createSession({
11
+ apiKey: process.env.FACTORY_API_KEY!,
12
+ cwd: process.cwd(),
13
+ });
14
+ const resumed = await resumeSession(session.sessionId, {
15
+ apiKey: process.env.FACTORY_API_KEY!,
16
+ });
12
17
 
13
18
  console.log(`created session: ${session.sessionId}`);
14
19
  console.log(`resumed session: ${resumed.sessionId}`);
@@ -7,13 +7,16 @@
7
7
 
8
8
  import { createSession, DroidMessageType } from '@factory/droid-sdk';
9
9
 
10
- const session = await createSession({ cwd: process.cwd() });
10
+ const session = await createSession({
11
+ apiKey: process.env.FACTORY_API_KEY!,
12
+ cwd: process.cwd(),
13
+ });
11
14
  let deltaCount = 0;
12
15
 
13
16
  try {
14
- for await (const msg of session.stream(
15
- 'Write a long history of computing.'
16
- )) {
17
+ for await (const msg of session.stream('Write a long history of computing.', {
18
+ includePartialMessages: true,
19
+ })) {
17
20
  if (msg.type !== DroidMessageType.AssistantTextDelta) {
18
21
  continue;
19
22
  }
@@ -12,7 +12,9 @@ async function streamText(
12
12
  prompt: string
13
13
  ): Promise<string> {
14
14
  let text = '';
15
- for await (const msg of session.stream(prompt)) {
15
+ for await (const msg of session.stream(prompt, {
16
+ includePartialMessages: true,
17
+ })) {
16
18
  if (msg.type === DroidMessageType.AssistantTextDelta) {
17
19
  text += msg.text;
18
20
  }
@@ -20,7 +22,10 @@ async function streamText(
20
22
  return text;
21
23
  }
22
24
 
23
- const session = await createSession({ cwd: process.cwd() });
25
+ const session = await createSession({
26
+ apiKey: process.env.FACTORY_API_KEY!,
27
+ cwd: process.cwd(),
28
+ });
24
29
 
25
30
  try {
26
31
  console.log(`Session: ${session.sessionId}\n`);
@@ -20,6 +20,7 @@ const outputPath = join(tempDir, 'hello.txt');
20
20
 
21
21
  try {
22
22
  await run(`Create ${outputPath} with the text "Hello, World!"`, {
23
+ apiKey: process.env.FACTORY_API_KEY!,
23
24
  cwd: process.cwd(),
24
25
  permissionHandler(params) {
25
26
  const onlyCreatesExpectedFile = params.toolUses.every(
@@ -3,6 +3,7 @@ import { OutputFormatType, run } from '@factory/droid-sdk';
3
3
  type FavoriteNumber = { favoriteNumber: number };
4
4
 
5
5
  const result = await run('Pick a favorite number between 1 and 42.', {
6
+ apiKey: process.env.FACTORY_API_KEY!,
6
7
  cwd: process.cwd(),
7
8
  outputFormat: {
8
9
  type: OutputFormatType.JsonSchema,
@@ -22,6 +22,7 @@ async function main(): Promise<void> {
22
22
  console.log(`Sending prompt: "${prompt}"\n`);
23
23
 
24
24
  const result = await run(prompt, {
25
+ apiKey: process.env.FACTORY_API_KEY!,
25
26
  cwd: process.cwd(),
26
27
  });
27
28
 
package/examples/run.ts CHANGED
@@ -17,6 +17,7 @@ async function main(): Promise<void> {
17
17
  console.log(`Sending prompt: "${text}"\n`);
18
18
 
19
19
  const result = await run(text, {
20
+ apiKey: process.env.FACTORY_API_KEY!,
20
21
  cwd: process.cwd(),
21
22
  });
22
23
 
@@ -22,6 +22,7 @@ const sdkTools = createSdkMcpServer({
22
22
  });
23
23
 
24
24
  const session = await createSession({
25
+ apiKey: process.env.FACTORY_API_KEY!,
25
26
  execPath,
26
27
  mcpServers: [sdkTools],
27
28
  cwd: process.cwd(),
@@ -30,7 +31,8 @@ const session = await createSession({
30
31
 
31
32
  try {
32
33
  for await (const msg of session.stream(
33
- 'Use the favorite_number tool for Ada and tell me the answer.'
34
+ 'Use the favorite_number tool for Ada and tell me the answer.',
35
+ { includePartialMessages: true }
34
36
  )) {
35
37
  if (msg.type === DroidMessageType.AssistantTextDelta) {
36
38
  process.stdout.write(msg.text);
@@ -15,7 +15,10 @@ async function main(): Promise<void> {
15
15
 
16
16
  console.log(`Sending prompt: "${prompt}"\n`);
17
17
 
18
- const session = await createSession({ cwd: process.cwd() });
18
+ const session = await createSession({
19
+ apiKey: process.env.FACTORY_API_KEY!,
20
+ cwd: process.cwd(),
21
+ });
19
22
 
20
23
  try {
21
24
  for await (const msg of session.stream(prompt)) {
@@ -22,6 +22,7 @@ const outputPath = join(tempDir, 'hello.txt');
22
22
 
23
23
  try {
24
24
  const session = await createSession({
25
+ apiKey: process.env.FACTORY_API_KEY!,
25
26
  cwd: process.cwd(),
26
27
  interactionMode: DroidInteractionMode.Spec,
27
28
  specModeReasoningEffort: ReasoningEffort.High,
@@ -22,6 +22,7 @@ const outputPath = join(tempDir, 'hello.txt');
22
22
 
23
23
  try {
24
24
  const session = await createSession({
25
+ apiKey: process.env.FACTORY_API_KEY!,
25
26
  cwd: process.cwd(),
26
27
  interactionMode: DroidInteractionMode.Spec,
27
28
  specModeReasoningEffort: ReasoningEffort.High,
@@ -38,6 +38,7 @@ async function main(): Promise<void> {
38
38
  console.log(`Sending prompt: "${prompt}"\n`);
39
39
 
40
40
  const result = await run(prompt, {
41
+ apiKey: process.env.FACTORY_API_KEY!,
41
42
  cwd: process.cwd(),
42
43
  outputFormat,
43
44
  });