@love-moon/ai-sdk 0.2.38 → 0.2.39

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/client.d.ts CHANGED
@@ -55,10 +55,12 @@ export class RemoteAiSession extends EventEmitter<[never]> {
55
55
  setSessionReplyTarget(replyTo: any): void;
56
56
  ensureSessionInfo(): Promise<any>;
57
57
  getSessionUsageSummary(): Promise<any>;
58
+ interruptCurrentTurn(): Promise<any>;
58
59
  runTurn(promptText: any, options?: {}): Promise<any>;
59
60
  close(): Promise<void>;
60
- callWorker(method: any, args?: any[], { progressHandler }?: {
61
+ callWorker(method: any, args?: any[], { progressHandler, messageType }?: {
61
62
  progressHandler?: null | undefined;
63
+ messageType?: string | undefined;
62
64
  }): Promise<any>;
63
65
  handleWorkerStderr(line: any): void;
64
66
  handleWorkerLine(line: any): void;
@@ -104,6 +106,7 @@ declare class LocalAiSessionProxy extends EventEmitter<[never]> {
104
106
  setSessionReplyTarget(replyTarget: any): void;
105
107
  ensureSessionInfo(): Promise<any>;
106
108
  getSessionUsageSummary(): Promise<any>;
109
+ interruptCurrentTurn(): Promise<any>;
107
110
  runTurn(promptText: any, options?: {}): Promise<any>;
108
111
  close(): Promise<void>;
109
112
  }
package/dist/client.js CHANGED
@@ -168,6 +168,11 @@ export class RemoteAiSession extends EventEmitter {
168
168
  async getSessionUsageSummary() {
169
169
  return this.callWorker("getSessionUsageSummary", []);
170
170
  }
171
+ async interruptCurrentTurn() {
172
+ return this.callWorker("interruptCurrentTurn", [], {
173
+ messageType: "control",
174
+ });
175
+ }
171
176
  async runTurn(promptText, options = {}) {
172
177
  const { onProgress, ...restOptions } = options || {};
173
178
  return this.callWorker("runTurn", [promptText, restOptions], {
@@ -214,7 +219,7 @@ export class RemoteAiSession extends EventEmitter {
214
219
  await this.exitPromise;
215
220
  }
216
221
  }
217
- async callWorker(method, args = [], { progressHandler = null } = {}) {
222
+ async callWorker(method, args = [], { progressHandler = null, messageType = "request" } = {}) {
218
223
  if (this.closed) {
219
224
  throw createSessionClosedError();
220
225
  }
@@ -224,7 +229,7 @@ export class RemoteAiSession extends EventEmitter {
224
229
  }
225
230
  const requestId = this.nextRequestId++;
226
231
  const payload = {
227
- type: "request",
232
+ type: messageType,
228
233
  id: requestId,
229
234
  method,
230
235
  args,
@@ -566,6 +571,13 @@ class LocalAiSessionProxy extends EventEmitter {
566
571
  const session = await this.readyPromise;
567
572
  return await session.getSessionUsageSummary();
568
573
  }
574
+ async interruptCurrentTurn() {
575
+ const session = await this.readyPromise;
576
+ if (typeof session.interruptCurrentTurn === "function") {
577
+ return await session.interruptCurrentTurn();
578
+ }
579
+ return false;
580
+ }
569
581
  async runTurn(promptText, options = {}) {
570
582
  const session = await this.readyPromise;
571
583
  return await session.runTurn(promptText, options);
@@ -15,13 +15,49 @@ function appendProviderModulePaths(parts, value) {
15
15
  if (!raw) {
16
16
  return;
17
17
  }
18
- for (const item of raw.split(process.platform === "win32" ? ";" : ":")) {
18
+ for (const item of splitProviderModulePathString(raw)) {
19
19
  const normalized = item.trim();
20
20
  if (normalized) {
21
21
  parts.push(normalized);
22
22
  }
23
23
  }
24
24
  }
25
+ function looksLikeProviderModulePath(value) {
26
+ const normalized = String(value || "").trim();
27
+ if (!normalized) {
28
+ return false;
29
+ }
30
+ return (normalized.startsWith("/") ||
31
+ normalized.startsWith("./") ||
32
+ normalized.startsWith("../") ||
33
+ normalized.startsWith("~/") ||
34
+ normalized.startsWith("file:") ||
35
+ normalized.includes("/") ||
36
+ normalized.includes("\\") ||
37
+ /\.[cm]?[jt]sx?$/i.test(normalized) ||
38
+ /^[A-Za-z]:[\\/]/.test(normalized));
39
+ }
40
+ function splitProviderModulePathString(raw) {
41
+ const normalized = String(raw || "").trim();
42
+ if (!normalized) {
43
+ return [];
44
+ }
45
+ const platformParts = normalized
46
+ .split(path.delimiter)
47
+ .map((item) => item.trim())
48
+ .filter(Boolean);
49
+ if (platformParts.length > 1 || !normalized.includes(",")) {
50
+ return platformParts;
51
+ }
52
+ const commaParts = normalized
53
+ .split(",")
54
+ .map((item) => item.trim())
55
+ .filter(Boolean);
56
+ if (commaParts.length > 1 && commaParts.every(looksLikeProviderModulePath)) {
57
+ return commaParts;
58
+ }
59
+ return platformParts;
60
+ }
25
61
  function listProviderModulePathsFromValue(rawValue) {
26
62
  const parts = [];
27
63
  appendProviderModulePaths(parts, rawValue);
@@ -121,7 +121,7 @@ export class ClaudeAgentSdkSession extends EventEmitter<[never]> {
121
121
  handleSdkMessage(message: any, currentTurn: any, { onProgress }: {
122
122
  onProgress: any;
123
123
  }): Promise<void>;
124
- interruptCurrentTurn(): Promise<void>;
124
+ interruptCurrentTurn(): Promise<boolean>;
125
125
  runTurn(promptText: any, { useInitialImages, onProgress }?: {
126
126
  useInitialImages?: boolean | undefined;
127
127
  onProgress?: null | undefined;
@@ -680,7 +680,7 @@ export class ClaudeAgentSdkSession extends EventEmitter {
680
680
  async interruptCurrentTurn() {
681
681
  const currentTurn = this.currentTurn;
682
682
  if (!currentTurn) {
683
- return;
683
+ return false;
684
684
  }
685
685
  try {
686
686
  await currentTurn.query?.interrupt?.();
@@ -700,6 +700,7 @@ export class ClaudeAgentSdkSession extends EventEmitter {
700
700
  catch {
701
701
  // best effort
702
702
  }
703
+ return true;
703
704
  }
704
705
  async runTurn(promptText, { useInitialImages = false, onProgress = null } = {}) {
705
706
  if (this.closeRequested) {
@@ -149,7 +149,7 @@ export class CodexAppServerSession extends EventEmitter<[never]> {
149
149
  handleTransportFailure(error: any): void;
150
150
  handleTransportExit(payload: any): void;
151
151
  maybeEmitAuthRequired(error: any): void;
152
- interruptCurrentTurn(): Promise<void>;
152
+ interruptCurrentTurn(): Promise<boolean>;
153
153
  runTurn(promptText: any, { useInitialImages }?: {
154
154
  useInitialImages?: boolean | undefined;
155
155
  }): Promise<{
@@ -851,17 +851,19 @@ export class CodexAppServerSession extends EventEmitter {
851
851
  async interruptCurrentTurn() {
852
852
  const currentTurn = this.currentTurn;
853
853
  if (!currentTurn || !this.sessionId || !currentTurn.turnId) {
854
- return;
854
+ return false;
855
855
  }
856
856
  try {
857
857
  await this.transport.request("turn/interrupt", {
858
858
  threadId: this.sessionId,
859
859
  turnId: currentTurn.turnId,
860
860
  });
861
+ return true;
861
862
  }
862
863
  catch {
863
864
  // best effort
864
865
  }
866
+ return false;
865
867
  }
866
868
  async runTurn(promptText, { useInitialImages = false } = {}) {
867
869
  if (this.closeRequested) {
@@ -143,7 +143,7 @@ export class KimiCliSession extends EventEmitter<[never]> {
143
143
  handleWireEvent(type: any, payload: any): Promise<void>;
144
144
  handleTransportFailure(error: any): void;
145
145
  handleTransportExit(payload: any): void;
146
- interruptCurrentTurn(): Promise<void>;
146
+ interruptCurrentTurn(): Promise<boolean>;
147
147
  runTurn(promptText: any, { useInitialImages, onProgress }?: {
148
148
  useInitialImages?: boolean | undefined;
149
149
  onProgress?: null | undefined;
@@ -812,14 +812,16 @@ export class KimiCliSession extends EventEmitter {
812
812
  }
813
813
  async interruptCurrentTurn() {
814
814
  if (!this.currentTurn) {
815
- return;
815
+ return false;
816
816
  }
817
817
  try {
818
818
  await this.transport.request("cancel", {});
819
+ return true;
819
820
  }
820
821
  catch {
821
822
  // best effort
822
823
  }
824
+ return false;
823
825
  }
824
826
  async runTurn(promptText, { useInitialImages = false, onProgress = null } = {}) {
825
827
  if (this.closeRequested || this.closed) {
@@ -163,7 +163,7 @@ export class OpencodeSdkSession extends EventEmitter<[never]> {
163
163
  handleOpencodeEvent(event: any): Promise<void>;
164
164
  handleTransportFailure(error: any): void;
165
165
  handleTransportExit(payload: any): void;
166
- interruptCurrentTurn(): Promise<void>;
166
+ interruptCurrentTurn(): Promise<boolean>;
167
167
  runTurn(promptText: any, { useInitialImages, onProgress }?: {
168
168
  useInitialImages?: boolean | undefined;
169
169
  onProgress?: null | undefined;
@@ -1119,7 +1119,7 @@ export class OpencodeSdkSession extends EventEmitter {
1119
1119
  async interruptCurrentTurn() {
1120
1120
  const currentTurn = this.currentTurn;
1121
1121
  if (!currentTurn || !this.client?.session || !this.sessionId) {
1122
- return;
1122
+ return false;
1123
1123
  }
1124
1124
  try {
1125
1125
  currentTurn.abortController?.abort?.();
@@ -1129,10 +1129,12 @@ export class OpencodeSdkSession extends EventEmitter {
1129
1129
  }
1130
1130
  try {
1131
1131
  await this.client.session.abort({ sessionID: this.sessionId }, { throwOnError: true, responseStyle: "data" });
1132
+ return true;
1132
1133
  }
1133
1134
  catch {
1134
1135
  // best effort
1135
1136
  }
1137
+ return true;
1136
1138
  }
1137
1139
  async runTurn(promptText, { useInitialImages = false, onProgress = null } = {}) {
1138
1140
  if (this.closeRequested) {
package/dist/worker.js CHANGED
@@ -85,6 +85,24 @@ async function handleRequest(message) {
85
85
  process.exit(0);
86
86
  }
87
87
  }
88
+ async function dispatchMessage(message) {
89
+ try {
90
+ if (message?.type === "create") {
91
+ await handleCreate(message);
92
+ return;
93
+ }
94
+ if (message?.type === "request" || message?.type === "control") {
95
+ await handleRequest(message);
96
+ }
97
+ }
98
+ catch (error) {
99
+ send({
100
+ type: message?.type === "create" ? "create_error" : "response",
101
+ id: message?.id,
102
+ error: serializeError(error),
103
+ });
104
+ }
105
+ }
88
106
  async function closeSession() {
89
107
  if (!session || typeof session.close !== "function") {
90
108
  return;
@@ -121,42 +139,31 @@ process.stdin.on("end", async () => {
121
139
  const input = readline.createInterface({ input: process.stdin });
122
140
  let workQueue = Promise.resolve();
123
141
  input.on("line", (line) => {
142
+ const normalized = String(line || "").trim();
143
+ if (!normalized) {
144
+ return;
145
+ }
146
+ let message;
147
+ try {
148
+ message = JSON.parse(normalized);
149
+ }
150
+ catch (error) {
151
+ send({
152
+ type: "event",
153
+ name: "worker_error",
154
+ payload: serializeError(error),
155
+ });
156
+ return;
157
+ }
158
+ if (message?.type === "control") {
159
+ void dispatchMessage(message);
160
+ return;
161
+ }
124
162
  workQueue = workQueue
125
163
  .catch(() => {
126
164
  // keep queue alive after previous failure
127
165
  })
128
166
  .then(async () => {
129
- const normalized = String(line || "").trim();
130
- if (!normalized) {
131
- return;
132
- }
133
- let message;
134
- try {
135
- message = JSON.parse(normalized);
136
- }
137
- catch (error) {
138
- send({
139
- type: "event",
140
- name: "worker_error",
141
- payload: serializeError(error),
142
- });
143
- return;
144
- }
145
- try {
146
- if (message?.type === "create") {
147
- await handleCreate(message);
148
- return;
149
- }
150
- if (message?.type === "request") {
151
- await handleRequest(message);
152
- }
153
- }
154
- catch (error) {
155
- send({
156
- type: message?.type === "create" ? "create_error" : "response",
157
- id: message?.id,
158
- error: serializeError(error),
159
- });
160
- }
167
+ await dispatchMessage(message);
161
168
  });
162
169
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@love-moon/ai-sdk",
3
- "version": "0.2.38",
3
+ "version": "0.2.39",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,5 +25,5 @@
25
25
  "@types/node": "^22.10.2",
26
26
  "typescript": "^5.6.3"
27
27
  },
28
- "gitCommitId": "6bf5515"
28
+ "gitCommitId": "30204c8"
29
29
  }