@letta-ai/letta-code-sdk 0.0.5 → 0.0.6

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/dist/index.js CHANGED
@@ -20,6 +20,10 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
  // src/transport.ts
21
21
  import { spawn } from "node:child_process";
22
22
  import { createInterface } from "node:readline";
23
+ function sdkLog(tag, ...args) {
24
+ if (process.env.DEBUG_SDK)
25
+ console.error(`[SDK-Transport] [${tag}]`, ...args);
26
+ }
23
27
 
24
28
  class SubprocessTransport {
25
29
  options;
@@ -29,21 +33,25 @@ class SubprocessTransport {
29
33
  messageResolvers = [];
30
34
  closed = false;
31
35
  agentId;
36
+ wireMessageCount = 0;
37
+ lastMessageAt = 0;
32
38
  constructor(options = {}) {
33
39
  this.options = options;
34
40
  }
35
41
  async connect() {
36
42
  const args = this.buildArgs();
37
43
  const cliPath = await this.findCli();
38
- if (process.env.DEBUG) {
39
- console.log("[letta-code-sdk] Using CLI:", cliPath);
40
- console.log("[letta-code-sdk] Args:", args.join(" "));
41
- }
44
+ sdkLog("connect", `CLI: ${cliPath}`);
45
+ sdkLog("connect", `args: ${args.join(" ")}`);
46
+ sdkLog("connect", `cwd: ${this.options.cwd || process.cwd()}`);
47
+ sdkLog("connect", `permissionMode: ${this.options.permissionMode || "default"}`);
42
48
  this.process = spawn("node", [cliPath, ...args], {
43
49
  cwd: this.options.cwd || process.cwd(),
44
50
  stdio: ["pipe", "pipe", "pipe"],
45
51
  env: { ...process.env }
46
52
  });
53
+ const pid = this.process.pid;
54
+ sdkLog("connect", `CLI process spawned, pid=${pid}`);
47
55
  if (!this.process.stdout || !this.process.stdin) {
48
56
  throw new Error("Failed to create subprocess pipes");
49
57
  }
@@ -57,7 +65,9 @@ class SubprocessTransport {
57
65
  try {
58
66
  const msg = JSON.parse(line);
59
67
  this.handleMessage(msg);
60
- } catch {}
68
+ } catch {
69
+ sdkLog("stdout", `[non-JSON] ${line.slice(0, 500)}`);
70
+ }
61
71
  });
62
72
  if (this.process.stderr) {
63
73
  this.process.stderr.on("data", (data) => {
@@ -67,11 +77,16 @@ class SubprocessTransport {
67
77
  }
68
78
  });
69
79
  }
70
- this.process.on("close", (code) => {
71
- this.closed = true;
80
+ this.process.on("close", (code, signal) => {
72
81
  if (code !== 0 && code !== null) {
73
82
  console.error(`[letta-code-sdk] CLI process exited with code ${code}`);
74
83
  }
84
+ sdkLog("close", `CLI process exited: pid=${pid} code=${code} signal=${signal} wireMessages=${this.wireMessageCount} msSinceLastMsg=${this.lastMessageAt ? Date.now() - this.lastMessageAt : 0} pendingResolvers=${this.messageResolvers.length} queueLen=${this.messageQueue.length}`);
85
+ this.closed = true;
86
+ for (const resolve of this.messageResolvers) {
87
+ resolve(null);
88
+ }
89
+ this.messageResolvers = [];
75
90
  });
76
91
  this.process.on("error", (err) => {
77
92
  console.error("[letta-code-sdk] CLI process error:", err);
@@ -80,8 +95,12 @@ class SubprocessTransport {
80
95
  }
81
96
  async write(data) {
82
97
  if (!this.process?.stdin || this.closed) {
83
- throw new Error("Transport not connected");
98
+ const err = new Error(`Transport not connected (closed=${this.closed}, pid=${this.process?.pid}, stdin=${!!this.process?.stdin})`);
99
+ sdkLog("write", err.message);
100
+ throw err;
84
101
  }
102
+ const payload = data;
103
+ sdkLog("write", `type=${payload.type} subtype=${payload.request?.subtype || payload.response?.subtype || "N/A"}`);
85
104
  this.process.stdin.write(JSON.stringify(data) + `
86
105
  `);
87
106
  }
@@ -90,8 +109,10 @@ class SubprocessTransport {
90
109
  return this.messageQueue.shift();
91
110
  }
92
111
  if (this.closed) {
112
+ sdkLog("read", `returning null (closed), total wireMessages=${this.wireMessageCount}`);
93
113
  return null;
94
114
  }
115
+ sdkLog("read", `waiting for next message (resolvers=${this.messageResolvers.length + 1}, queue=${this.messageQueue.length})`);
95
116
  return new Promise((resolve) => {
96
117
  this.messageResolvers.push(resolve);
97
118
  });
@@ -99,12 +120,15 @@ class SubprocessTransport {
99
120
  async* messages() {
100
121
  while (true) {
101
122
  const msg = await this.read();
102
- if (msg === null)
123
+ if (msg === null) {
124
+ sdkLog("messages", `iterator ending (closed=${this.closed}, wireMessages=${this.wireMessageCount})`);
103
125
  break;
126
+ }
104
127
  yield msg;
105
128
  }
106
129
  }
107
130
  close() {
131
+ sdkLog("close", `explicit close called (wireMessages=${this.wireMessageCount}, pendingResolvers=${this.messageResolvers.length}, pid=${this.process?.pid})`);
108
132
  if (this.process) {
109
133
  this.process.stdin?.end();
110
134
  this.process.kill();
@@ -120,8 +144,22 @@ class SubprocessTransport {
120
144
  return this.closed;
121
145
  }
122
146
  handleMessage(msg) {
147
+ this.wireMessageCount++;
148
+ this.lastMessageAt = Date.now();
149
+ const wirePayload = msg;
150
+ const msgType = wirePayload.message_type || wirePayload.subtype || "";
151
+ sdkLog("wire", `#${this.wireMessageCount} type=${msg.type} ${msgType ? `msg_type=${msgType}` : ""} resolvers=${this.messageResolvers.length} queue=${this.messageQueue.length}`);
152
+ if (msg.type === "result") {
153
+ const result = wirePayload;
154
+ sdkLog("wire", `RESULT: subtype=${result.subtype} stop_reason=${result.stop_reason || "N/A"} duration=${result.duration_ms}ms resultLen=${result.result?.length || 0}`);
155
+ }
123
156
  if (msg.type === "system" && "subtype" in msg && msg.subtype === "init") {
124
157
  this.agentId = msg.agent_id;
158
+ sdkLog("wire", `INIT: agent_id=${this.agentId}`);
159
+ }
160
+ if (msg.type === "control_request") {
161
+ const req = wirePayload;
162
+ sdkLog("wire", `CONTROL_REQUEST: id=${req.request_id} subtype=${req.request?.subtype} tool=${req.request?.tool_name || "N/A"}`);
125
163
  }
126
164
  if (this.messageResolvers.length > 0) {
127
165
  const resolve = this.messageResolvers.shift();
@@ -146,7 +184,7 @@ class SubprocessTransport {
146
184
  } else if (this.options.defaultConversation) {
147
185
  args.push("--default");
148
186
  }
149
- } else if (this.options.promptMode) {} else if (this.options.createOnly) {
187
+ } else if (this.options.createOnly) {
150
188
  args.push("--new-agent");
151
189
  } else if (this.options.newConversation) {
152
190
  args.push("--new");
@@ -154,6 +192,9 @@ class SubprocessTransport {
154
192
  if (this.options.model) {
155
193
  args.push("-m", this.options.model);
156
194
  }
195
+ if (this.options.embedding) {
196
+ args.push("--embedding", this.options.embedding);
197
+ }
157
198
  if (this.options.systemPrompt !== undefined) {
158
199
  if (typeof this.options.systemPrompt === "string") {
159
200
  const validPresets = [
@@ -212,12 +253,15 @@ class SubprocessTransport {
212
253
  }
213
254
  if (this.options.permissionMode === "bypassPermissions") {
214
255
  args.push("--yolo");
215
- } else if (this.options.permissionMode === "acceptEdits") {
216
- args.push("--accept-edits");
256
+ } else if (this.options.permissionMode && this.options.permissionMode !== "default") {
257
+ args.push("--permission-mode", this.options.permissionMode);
217
258
  }
218
259
  if (this.options.allowedTools) {
219
260
  args.push("--allowedTools", this.options.allowedTools.join(","));
220
261
  }
262
+ if (this.options.disallowedTools) {
263
+ args.push("--disallowedTools", this.options.disallowedTools.join(","));
264
+ }
221
265
  return args;
222
266
  }
223
267
  async findCli() {
@@ -251,7 +295,27 @@ class SubprocessTransport {
251
295
  }
252
296
  }
253
297
 
298
+ // src/interactiveToolPolicy.ts
299
+ var INTERACTIVE_APPROVAL_TOOLS = new Set([
300
+ "AskUserQuestion",
301
+ "EnterPlanMode",
302
+ "ExitPlanMode"
303
+ ]);
304
+ var RUNTIME_USER_INPUT_TOOLS = new Set(["AskUserQuestion", "ExitPlanMode"]);
305
+ var HEADLESS_AUTO_ALLOW_TOOLS = new Set(["EnterPlanMode"]);
306
+ function requiresRuntimeUserInput(toolName) {
307
+ return RUNTIME_USER_INPUT_TOOLS.has(toolName);
308
+ }
309
+ function isHeadlessAutoAllowTool(toolName) {
310
+ return HEADLESS_AUTO_ALLOW_TOOLS.has(toolName);
311
+ }
312
+
254
313
  // src/session.ts
314
+ function sessionLog(tag, ...args) {
315
+ if (process.env.DEBUG_SDK)
316
+ console.error(`[SDK-Session] [${tag}]`, ...args);
317
+ }
318
+
255
319
  class Session {
256
320
  options;
257
321
  transport;
@@ -259,77 +323,216 @@ class Session {
259
323
  _sessionId = null;
260
324
  _conversationId = null;
261
325
  initialized = false;
326
+ externalTools = new Map;
262
327
  constructor(options = {}) {
263
328
  this.options = options;
264
329
  this.transport = new SubprocessTransport(options);
330
+ if (options.tools) {
331
+ for (const tool of options.tools) {
332
+ this.externalTools.set(tool.name, tool);
333
+ }
334
+ }
265
335
  }
266
336
  async initialize() {
267
337
  if (this.initialized) {
268
338
  throw new Error("Session already initialized");
269
339
  }
340
+ sessionLog("init", "connecting transport...");
270
341
  await this.transport.connect();
342
+ sessionLog("init", "transport connected, sending initialize request");
271
343
  await this.transport.write({
272
344
  type: "control_request",
273
345
  request_id: "init_1",
274
346
  request: { subtype: "initialize" }
275
347
  });
348
+ sessionLog("init", "waiting for init message from CLI...");
276
349
  for await (const msg of this.transport.messages()) {
350
+ sessionLog("init", `received wire message: type=${msg.type}`);
277
351
  if (msg.type === "system" && "subtype" in msg && msg.subtype === "init") {
278
352
  const initMsg = msg;
279
353
  this._agentId = initMsg.agent_id;
280
354
  this._sessionId = initMsg.session_id;
281
355
  this._conversationId = initMsg.conversation_id;
282
356
  this.initialized = true;
357
+ if (this.externalTools.size > 0) {
358
+ await this.registerExternalTools();
359
+ }
360
+ const allTools = [
361
+ ...initMsg.tools,
362
+ ...Array.from(this.externalTools.keys())
363
+ ];
364
+ sessionLog("init", `initialized: agent=${initMsg.agent_id} conversation=${initMsg.conversation_id} model=${initMsg.model} tools=${allTools.length} (${this.externalTools.size} external)`);
283
365
  return {
284
366
  type: "init",
285
367
  agentId: initMsg.agent_id,
286
368
  sessionId: initMsg.session_id,
287
369
  conversationId: initMsg.conversation_id,
288
370
  model: initMsg.model,
289
- tools: initMsg.tools
371
+ tools: allTools
290
372
  };
291
373
  }
292
374
  }
375
+ sessionLog("init", "ERROR: transport closed before init message received");
293
376
  throw new Error("Failed to initialize session - no init message received");
294
377
  }
295
378
  async send(message) {
296
379
  if (!this.initialized) {
380
+ sessionLog("send", "auto-initializing (not yet initialized)");
297
381
  await this.initialize();
298
382
  }
383
+ const preview = typeof message === "string" ? message.slice(0, 100) : Array.isArray(message) ? `[multimodal: ${message.length} parts]` : String(message).slice(0, 100);
384
+ sessionLog("send", `sending message: ${preview}${typeof message === "string" && message.length > 100 ? "..." : ""}`);
299
385
  await this.transport.write({
300
386
  type: "user",
301
387
  message: { role: "user", content: message }
302
388
  });
389
+ sessionLog("send", "message written to transport");
303
390
  }
304
391
  async* stream() {
392
+ const streamStart = Date.now();
393
+ let yieldCount = 0;
394
+ let dropCount = 0;
395
+ let gotResult = false;
396
+ sessionLog("stream", `starting stream (agent=${this._agentId}, conversation=${this._conversationId})`);
305
397
  for await (const wireMsg of this.transport.messages()) {
306
398
  if (wireMsg.type === "control_request") {
307
399
  const controlReq = wireMsg;
308
- if (controlReq.request.subtype === "can_use_tool") {
400
+ const subtype = controlReq.request.subtype;
401
+ sessionLog("stream", `control_request: subtype=${subtype} tool=${controlReq.request.tool_name || "N/A"}`);
402
+ if (subtype === "can_use_tool") {
309
403
  await this.handleCanUseTool(controlReq.request_id, controlReq.request);
310
404
  continue;
311
405
  }
406
+ if (subtype === "execute_external_tool") {
407
+ const rawReq = controlReq.request;
408
+ await this.handleExecuteExternalTool(controlReq.request_id, {
409
+ subtype: "execute_external_tool",
410
+ tool_call_id: rawReq.tool_call_id,
411
+ tool_name: rawReq.tool_name,
412
+ input: rawReq.input
413
+ });
414
+ continue;
415
+ }
312
416
  }
313
417
  const sdkMsg = this.transformMessage(wireMsg);
314
418
  if (sdkMsg) {
419
+ yieldCount++;
420
+ sessionLog("stream", `yield #${yieldCount}: type=${sdkMsg.type}${sdkMsg.type === "result" ? ` success=${sdkMsg.success} error=${sdkMsg.error || "none"}` : ""}`);
315
421
  yield sdkMsg;
316
422
  if (sdkMsg.type === "result") {
423
+ gotResult = true;
317
424
  break;
318
425
  }
426
+ } else {
427
+ dropCount++;
428
+ const wireMsgAny = wireMsg;
429
+ sessionLog("stream", `DROPPED wire message #${dropCount}: type=${wireMsg.type} message_type=${wireMsgAny.message_type || "N/A"} subtype=${wireMsgAny.subtype || "N/A"}`);
430
+ }
431
+ }
432
+ const elapsed = Date.now() - streamStart;
433
+ sessionLog("stream", `stream ended: duration=${elapsed}ms yielded=${yieldCount} dropped=${dropCount} gotResult=${gotResult}`);
434
+ if (!gotResult) {
435
+ sessionLog("stream", `WARNING: stream ended WITHOUT a result message -- transport may have closed unexpectedly`);
436
+ }
437
+ }
438
+ async registerExternalTools() {
439
+ const toolDefs = Array.from(this.externalTools.values()).map((tool) => ({
440
+ name: tool.name,
441
+ label: tool.label,
442
+ description: tool.description,
443
+ parameters: this.schemaToJsonSchema(tool.parameters)
444
+ }));
445
+ sessionLog("registerTools", `registering ${toolDefs.length} external tools: ${toolDefs.map((t) => t.name).join(", ")}`);
446
+ await this.transport.write({
447
+ type: "control_request",
448
+ request_id: `register_tools_${Date.now()}`,
449
+ request: {
450
+ subtype: "register_external_tools",
451
+ tools: toolDefs
319
452
  }
453
+ });
454
+ }
455
+ schemaToJsonSchema(schema) {
456
+ if (schema && typeof schema === "object") {
457
+ const s = schema;
458
+ return {
459
+ type: s.type,
460
+ properties: s.properties,
461
+ required: s.required,
462
+ additionalProperties: s.additionalProperties,
463
+ description: s.description
464
+ };
465
+ }
466
+ return { type: "object" };
467
+ }
468
+ async handleExecuteExternalTool(requestId, req) {
469
+ const tool = this.externalTools.get(req.tool_name);
470
+ if (!tool) {
471
+ sessionLog("executeExternalTool", `ERROR: unknown tool ${req.tool_name}`);
472
+ await this.transport.write({
473
+ type: "control_response",
474
+ response: {
475
+ subtype: "external_tool_result",
476
+ request_id: requestId,
477
+ tool_call_id: req.tool_call_id,
478
+ content: [{ type: "text", text: `Unknown external tool: ${req.tool_name}` }],
479
+ is_error: true
480
+ }
481
+ });
482
+ return;
483
+ }
484
+ try {
485
+ sessionLog("executeExternalTool", `executing ${req.tool_name} (call_id=${req.tool_call_id})`);
486
+ const result = await tool.execute(req.tool_call_id, req.input);
487
+ await this.transport.write({
488
+ type: "control_response",
489
+ response: {
490
+ subtype: "external_tool_result",
491
+ request_id: requestId,
492
+ tool_call_id: req.tool_call_id,
493
+ content: result.content,
494
+ is_error: false
495
+ }
496
+ });
497
+ sessionLog("executeExternalTool", `${req.tool_name} completed successfully`);
498
+ } catch (err) {
499
+ const errorMessage = err instanceof Error ? err.message : String(err);
500
+ sessionLog("executeExternalTool", `${req.tool_name} failed: ${errorMessage}`);
501
+ await this.transport.write({
502
+ type: "control_response",
503
+ response: {
504
+ subtype: "external_tool_result",
505
+ request_id: requestId,
506
+ tool_call_id: req.tool_call_id,
507
+ content: [{ type: "text", text: `Tool execution error: ${errorMessage}` }],
508
+ is_error: true
509
+ }
510
+ });
320
511
  }
321
512
  }
322
513
  async handleCanUseTool(requestId, req) {
323
514
  let response;
324
- if (this.options.permissionMode === "bypassPermissions") {
515
+ const toolName = req.tool_name;
516
+ const hasCallback = typeof this.options.canUseTool === "function";
517
+ const toolNeedsRuntimeUserInput = requiresRuntimeUserInput(toolName);
518
+ const autoAllowWithoutCallback = isHeadlessAutoAllowTool(toolName);
519
+ sessionLog("canUseTool", `tool=${toolName} mode=${this.options.permissionMode || "default"} requestId=${requestId}`);
520
+ if (toolNeedsRuntimeUserInput && !hasCallback) {
521
+ response = {
522
+ behavior: "deny",
523
+ message: "No canUseTool callback registered",
524
+ interrupt: false
525
+ };
526
+ } else if (this.options.permissionMode === "bypassPermissions" && !toolNeedsRuntimeUserInput) {
527
+ sessionLog("canUseTool", `AUTO-ALLOW ${toolName} (bypassPermissions)`);
325
528
  response = {
326
529
  behavior: "allow",
327
530
  updatedInput: null,
328
531
  updatedPermissions: []
329
532
  };
330
- } else if (this.options.canUseTool) {
533
+ } else if (hasCallback) {
331
534
  try {
332
- const result = await this.options.canUseTool(req.tool_name, req.input);
535
+ const result = await this.options.canUseTool(toolName, req.input);
333
536
  if (result.behavior === "allow") {
334
537
  response = {
335
538
  behavior: "allow",
@@ -350,6 +553,13 @@ class Session {
350
553
  interrupt: false
351
554
  };
352
555
  }
556
+ } else if (autoAllowWithoutCallback) {
557
+ sessionLog("canUseTool", `AUTO-ALLOW ${toolName} (default behavior)`);
558
+ response = {
559
+ behavior: "allow",
560
+ updatedInput: null,
561
+ updatedPermissions: []
562
+ };
353
563
  } else {
354
564
  response = {
355
565
  behavior: "deny",
@@ -357,6 +567,8 @@ class Session {
357
567
  interrupt: false
358
568
  };
359
569
  }
570
+ const responseBehavior = "behavior" in response ? response.behavior : "unknown";
571
+ sessionLog("canUseTool", `responding: requestId=${requestId} behavior=${responseBehavior}`);
360
572
  await this.transport.write({
361
573
  type: "control_response",
362
574
  response: {
@@ -365,8 +577,10 @@ class Session {
365
577
  response
366
578
  }
367
579
  });
580
+ sessionLog("canUseTool", `response sent for ${toolName}`);
368
581
  }
369
582
  async abort() {
583
+ sessionLog("abort", `aborting session (agent=${this._agentId})`);
370
584
  await this.transport.write({
371
585
  type: "control_request",
372
586
  request_id: `interrupt-${Date.now()}`,
@@ -374,6 +588,7 @@ class Session {
374
588
  });
375
589
  }
376
590
  close() {
591
+ sessionLog("close", `closing session (agent=${this._agentId}, conversation=${this._conversationId})`);
377
592
  this.transport.close();
378
593
  }
379
594
  get agentId() {
@@ -459,6 +674,7 @@ class Session {
459
674
  success: msg.subtype === "success",
460
675
  result: msg.result,
461
676
  error: msg.subtype !== "success" ? msg.subtype : undefined,
677
+ stopReason: msg.stop_reason,
462
678
  durationMs: msg.duration_ms,
463
679
  totalCostUsd: msg.total_cost_usd,
464
680
  conversationId: msg.conversation_id
@@ -524,6 +740,97 @@ function validateCreateAgentOptions(options) {
524
740
  }
525
741
  }
526
742
  }
743
+ // src/tool-helpers.ts
744
+ function jsonResult(payload) {
745
+ return {
746
+ content: [
747
+ {
748
+ type: "text",
749
+ text: JSON.stringify(payload, null, 2)
750
+ }
751
+ ],
752
+ details: payload
753
+ };
754
+ }
755
+ function readStringParam(params, key, options = {}) {
756
+ const { required = false, trim = true, label = key, allowEmpty = false } = options;
757
+ const raw = params[key];
758
+ if (typeof raw !== "string") {
759
+ if (required)
760
+ throw new Error(`${label} required`);
761
+ return;
762
+ }
763
+ const value = trim ? raw.trim() : raw;
764
+ if (!value && !allowEmpty) {
765
+ if (required)
766
+ throw new Error(`${label} required`);
767
+ return;
768
+ }
769
+ return value;
770
+ }
771
+ function readNumberParam(params, key, options = {}) {
772
+ const { required = false, label = key, integer = false } = options;
773
+ const raw = params[key];
774
+ let value;
775
+ if (typeof raw === "number" && Number.isFinite(raw)) {
776
+ value = raw;
777
+ } else if (typeof raw === "string") {
778
+ const trimmed = raw.trim();
779
+ if (trimmed) {
780
+ const parsed = Number.parseFloat(trimmed);
781
+ if (Number.isFinite(parsed))
782
+ value = parsed;
783
+ }
784
+ }
785
+ if (value === undefined) {
786
+ if (required)
787
+ throw new Error(`${label} required`);
788
+ return;
789
+ }
790
+ return integer ? Math.trunc(value) : value;
791
+ }
792
+ function readBooleanParam(params, key, options = {}) {
793
+ const { required = false, label = key } = options;
794
+ const raw = params[key];
795
+ if (typeof raw === "boolean") {
796
+ return raw;
797
+ }
798
+ if (typeof raw === "string") {
799
+ const lower = raw.toLowerCase().trim();
800
+ if (lower === "true" || lower === "1" || lower === "yes")
801
+ return true;
802
+ if (lower === "false" || lower === "0" || lower === "no")
803
+ return false;
804
+ }
805
+ if (required)
806
+ throw new Error(`${label} required`);
807
+ return;
808
+ }
809
+ function readStringArrayParam(params, key, options = {}) {
810
+ const { required = false, label = key } = options;
811
+ const raw = params[key];
812
+ if (Array.isArray(raw)) {
813
+ const values = raw.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter(Boolean);
814
+ if (values.length === 0) {
815
+ if (required)
816
+ throw new Error(`${label} required`);
817
+ return;
818
+ }
819
+ return values;
820
+ }
821
+ if (typeof raw === "string") {
822
+ const value = raw.trim();
823
+ if (!value) {
824
+ if (required)
825
+ throw new Error(`${label} required`);
826
+ return;
827
+ }
828
+ return [value];
829
+ }
830
+ if (required)
831
+ throw new Error(`${label} required`);
832
+ return;
833
+ }
527
834
 
528
835
  // src/index.ts
529
836
  import { readFileSync } from "node:fs";
@@ -551,7 +858,7 @@ function resumeSession(id, options = {}) {
551
858
  }
552
859
  }
553
860
  async function prompt(message, agentId) {
554
- const session = agentId ? createSession(agentId) : new Session({ promptMode: true });
861
+ const session = agentId ? createSession(agentId) : createSession();
555
862
  try {
556
863
  await session.send(message);
557
864
  let result = null;
@@ -610,7 +917,12 @@ async function imageFromURL(url) {
610
917
  }
611
918
  export {
612
919
  resumeSession,
920
+ readStringParam,
921
+ readStringArrayParam,
922
+ readNumberParam,
923
+ readBooleanParam,
613
924
  prompt,
925
+ jsonResult,
614
926
  imageFromURL,
615
927
  imageFromFile,
616
928
  imageFromBase64,
@@ -619,4 +931,4 @@ export {
619
931
  Session
620
932
  };
621
933
 
622
- //# debugId=D4FF4806F62B360664756E2164756E21
934
+ //# debugId=63415FA0837719DA64756E2164756E21