@love-moon/ai-sdk 0.2.39 → 0.2.40

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.
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { pathToFileURL } from "node:url";
3
3
  import { loadEnvConfig } from "./shared.js";
4
- const BUILT_IN_BACKENDS = new Set(["codex", "claude", "kimi", "opencode"]);
4
+ const BUILT_IN_BACKENDS = new Set(["codex", "claude", "copilot", "kimi", "opencode"]);
5
5
  const registryPromises = new Map();
6
6
  let externalProviderImportNonce = 0;
7
7
  function appendProviderModulePaths(parts, value) {
@@ -122,9 +122,10 @@ export class ClaudeAgentSdkSession extends EventEmitter<[never]> {
122
122
  onProgress: any;
123
123
  }): Promise<void>;
124
124
  interruptCurrentTurn(): Promise<boolean>;
125
- runTurn(promptText: any, { useInitialImages, onProgress }?: {
125
+ runTurn(promptText: any, { useInitialImages, onProgress, jsonSchema }?: {
126
126
  useInitialImages?: boolean | undefined;
127
127
  onProgress?: null | undefined;
128
+ jsonSchema?: null | undefined;
128
129
  }): Promise<{
129
130
  text: string;
130
131
  usage: null;
@@ -143,6 +144,7 @@ export class ClaudeAgentSdkSession extends EventEmitter<[never]> {
143
144
  sessionId: any;
144
145
  totalCostUsd: number | undefined;
145
146
  modelUsage: any;
147
+ structuredOutput: any;
146
148
  };
147
149
  }>;
148
150
  close(): Promise<void>;
@@ -550,6 +550,7 @@ export class ClaudeAgentSdkSession extends EventEmitter {
550
550
  "systemPrompt",
551
551
  "thinking",
552
552
  "tools",
553
+ "outputFormat",
553
554
  ];
554
555
  for (const key of passthroughKeys) {
555
556
  const value = this.options[key];
@@ -702,7 +703,7 @@ export class ClaudeAgentSdkSession extends EventEmitter {
702
703
  }
703
704
  return true;
704
705
  }
705
- async runTurn(promptText, { useInitialImages = false, onProgress = null } = {}) {
706
+ async runTurn(promptText, { useInitialImages = false, onProgress = null, jsonSchema = null } = {}) {
706
707
  if (this.closeRequested) {
707
708
  throw this.createSessionClosedError();
708
709
  }
@@ -745,6 +746,10 @@ export class ClaudeAgentSdkSession extends EventEmitter {
745
746
  abortController.abort();
746
747
  currentTurn.query?.close?.();
747
748
  });
749
+ const previousOutputFormat = this.options.outputFormat;
750
+ if (jsonSchema && typeof jsonSchema === "object") {
751
+ this.options.outputFormat = { type: "json_schema", schema: jsonSchema };
752
+ }
748
753
  try {
749
754
  await this.emitWorkingStatus({
750
755
  phase: "turn_started",
@@ -787,9 +792,14 @@ export class ClaudeAgentSdkSession extends EventEmitter {
787
792
  : [],
788
793
  });
789
794
  }
790
- const responseText = normalizeText(resultMessage.result) ||
791
- currentTurn.fullText ||
792
- extractAssistantText(currentTurn.items.find((item) => item?.type === "assistant")?.message);
795
+ const structuredOutput = jsonSchema && resultMessage.structured_output && typeof resultMessage.structured_output === "object"
796
+ ? resultMessage.structured_output
797
+ : null;
798
+ const responseText = structuredOutput !== null
799
+ ? JSON.stringify(structuredOutput)
800
+ : normalizeText(resultMessage.result) ||
801
+ currentTurn.fullText ||
802
+ extractAssistantText(currentTurn.items.find((item) => item?.type === "assistant")?.message);
793
803
  if (!currentTurn.emittedAssistantMessage && responseText) {
794
804
  await this.emitAssistantMessage(responseText);
795
805
  }
@@ -815,6 +825,7 @@ export class ClaudeAgentSdkSession extends EventEmitter {
815
825
  ? Number(resultMessage.total_cost_usd)
816
826
  : undefined,
817
827
  modelUsage: resultMessage.modelUsage ? { ...resultMessage.modelUsage } : undefined,
828
+ structuredOutput: structuredOutput !== null ? structuredOutput : undefined,
818
829
  },
819
830
  };
820
831
  }
@@ -836,6 +847,14 @@ export class ClaudeAgentSdkSession extends EventEmitter {
836
847
  throw error;
837
848
  }
838
849
  finally {
850
+ if (jsonSchema && typeof jsonSchema === "object") {
851
+ if (previousOutputFormat !== undefined) {
852
+ this.options.outputFormat = previousOutputFormat;
853
+ }
854
+ else {
855
+ delete this.options.outputFormat;
856
+ }
857
+ }
839
858
  this.activeReplyTarget = "";
840
859
  if (this.currentTurn === currentTurn) {
841
860
  this.currentTurn = null;
@@ -150,8 +150,9 @@ export class CodexAppServerSession extends EventEmitter<[never]> {
150
150
  handleTransportExit(payload: any): void;
151
151
  maybeEmitAuthRequired(error: any): void;
152
152
  interruptCurrentTurn(): Promise<boolean>;
153
- runTurn(promptText: any, { useInitialImages }?: {
153
+ runTurn(promptText: any, { useInitialImages, jsonSchema }?: {
154
154
  useInitialImages?: boolean | undefined;
155
+ jsonSchema?: null | undefined;
155
156
  }): Promise<{
156
157
  text: string;
157
158
  usage: null;
@@ -38,6 +38,15 @@ function buildTurnInput(promptText) {
38
38
  },
39
39
  ];
40
40
  }
41
+ function injectJsonSchemaPrompt(promptText, jsonSchema) {
42
+ const schemaText = typeof jsonSchema === "string" ? jsonSchema : JSON.stringify(jsonSchema, null, 2);
43
+ return `You must respond with valid JSON that strictly conforms to the following JSON Schema. Do not include any markdown formatting or explanation outside the JSON object.
44
+
45
+ JSON Schema:
46
+ ${schemaText}
47
+
48
+ ${promptText}`;
49
+ }
41
50
  function normalizeItemId(value) {
42
51
  return typeof value === "string" ? value.trim() : "";
43
52
  }
@@ -198,7 +207,11 @@ export class CodexAppServerSession extends EventEmitter {
198
207
  const extraEnv = envConfig && typeof envConfig === "object" ? { ...envConfig, ...proxyEnv } : proxyEnv;
199
208
  this.transport = new CodexAppServerTransport({
200
209
  cwd: this.cwd,
201
- env: extraEnv,
210
+ env: {
211
+ ...extraEnv,
212
+ ...(options.env && typeof options.env === "object" ? options.env : {}),
213
+ },
214
+ ignoreCodexApiKey: options.ignoreCodexApiKey === true,
202
215
  logger: {
203
216
  log: (message) => {
204
217
  this.writeLog(message);
@@ -865,11 +878,14 @@ export class CodexAppServerSession extends EventEmitter {
865
878
  }
866
879
  return false;
867
880
  }
868
- async runTurn(promptText, { useInitialImages = false } = {}) {
881
+ async runTurn(promptText, { useInitialImages = false, jsonSchema = null } = {}) {
869
882
  if (this.closeRequested) {
870
883
  throw this.createSessionClosedError();
871
884
  }
872
- const effectivePrompt = this.buildPrompt(promptText, { useInitialImages });
885
+ let effectivePrompt = this.buildPrompt(promptText, { useInitialImages });
886
+ if (jsonSchema && typeof jsonSchema === "object" && effectivePrompt) {
887
+ effectivePrompt = injectJsonSchemaPrompt(effectivePrompt, jsonSchema);
888
+ }
873
889
  if (!effectivePrompt) {
874
890
  return {
875
891
  text: "",
@@ -0,0 +1,116 @@
1
+ export class CodexExecSession extends EventEmitter<[never]> {
2
+ constructor(backend: any, options?: {});
3
+ backend: string;
4
+ options: {};
5
+ logger: any;
6
+ cwd: any;
7
+ resumeSessionId: any;
8
+ sessionId: any;
9
+ sessionInfo: {
10
+ backend: string;
11
+ sessionId: any;
12
+ model: any;
13
+ };
14
+ history: any[];
15
+ closeRequested: boolean;
16
+ closed: boolean;
17
+ ignoreCodexApiKey: boolean;
18
+ currentTurn: {
19
+ child: null;
20
+ stdoutEvents: never[];
21
+ stderrTail: never[];
22
+ settled: boolean;
23
+ } | null;
24
+ currentTurnStatus: any;
25
+ sessionAnnounced: boolean;
26
+ sessionMessageHandler: any;
27
+ workingStatusHandler: any;
28
+ activeReplyTarget: string;
29
+ lastReplyTarget: string;
30
+ turnDeadlineMs: any;
31
+ env: any;
32
+ command: string;
33
+ baseArgs: string[];
34
+ writeLog(message: any): void;
35
+ trace(message: any): void;
36
+ get threadId(): any;
37
+ get threadOptions(): {
38
+ model: any;
39
+ modelProvider: any;
40
+ };
41
+ getSnapshot(): {
42
+ backend: string;
43
+ provider: string;
44
+ cwd: any;
45
+ sessionId: any;
46
+ sessionInfo: {
47
+ backend: string;
48
+ sessionId: any;
49
+ model: any;
50
+ } | null;
51
+ useSessionFileReplyStream: boolean;
52
+ resumeReady: boolean;
53
+ manualResume: null;
54
+ currentTurnStatus: any;
55
+ pid: any;
56
+ };
57
+ getSessionInfo(): {
58
+ backend: string;
59
+ sessionId: any;
60
+ model: any;
61
+ } | null;
62
+ getCurrentTurnStatus(): any;
63
+ ensureSessionInfo(): Promise<{
64
+ backend: string;
65
+ sessionId: any;
66
+ model: any;
67
+ } | null>;
68
+ getSessionUsageSummary(): Promise<{
69
+ sessionId: any;
70
+ sessionFilePath: undefined;
71
+ tokenUsagePercent: undefined;
72
+ contextUsagePercent: undefined;
73
+ tokenUsage: null;
74
+ rateLimits: null;
75
+ manualResume: null;
76
+ }>;
77
+ usesSessionFileReplyStream(): boolean;
78
+ setSessionMessageHandler(handler: any): void;
79
+ setWorkingStatusHandler(handler: any): void;
80
+ setSessionReplyTarget(replyTo: any): void;
81
+ getCurrentReplyTarget(): string | undefined;
82
+ announceSession(): void;
83
+ createSessionClosedError(): Error;
84
+ updateCurrentTurnStatus(payload: any): void;
85
+ emitWorkingStatus(payload: any, onProgress?: null): Promise<any>;
86
+ emitAssistantMessage(text: any): Promise<void>;
87
+ buildPrompt(promptText: any): string;
88
+ buildExecArgs({ useInitialImages, schemaFilePath, lastMessageFilePath }?: {
89
+ useInitialImages?: boolean | undefined;
90
+ schemaFilePath?: string | undefined;
91
+ lastMessageFilePath?: string | undefined;
92
+ }): string[];
93
+ maybeEmitAuthRequired(stderrTail: any): void;
94
+ runTurn(promptText: any, { useInitialImages, onProgress, jsonSchema }?: {
95
+ useInitialImages?: boolean | undefined;
96
+ onProgress?: null | undefined;
97
+ jsonSchema?: null | undefined;
98
+ }): Promise<{
99
+ text: string;
100
+ usage: null;
101
+ items: never[];
102
+ events: never[];
103
+ } | {
104
+ text: any;
105
+ usage: null;
106
+ items: any;
107
+ events: any;
108
+ provider: string;
109
+ metadata: {
110
+ source: string;
111
+ sessionId: any;
112
+ };
113
+ }>;
114
+ close(): Promise<void>;
115
+ }
116
+ import { EventEmitter } from "node:events";