@ycodium-ai/agent-codex 0.2.2130 → 0.2.2147

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.
Files changed (2) hide show
  1. package/dist/index.js +180 -48
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -92,6 +92,7 @@ var CODEX_CARD = {
92
92
 
93
93
  // src/codexInstance.ts
94
94
  import * as NodeProcess from "node:process";
95
+ import { ExecutorSpawnRefusedError } from "@ycodium-ai/plugin-api/executor";
95
96
 
96
97
  // src/codexAccount.ts
97
98
  import * as NodeFS from "node:fs";
@@ -755,6 +756,10 @@ function asString(value) {
755
756
  function asNumber(value) {
756
757
  return typeof value === "number" && Number.isFinite(value) ? value : null;
757
758
  }
759
+ function codexVersionFromInitialize(initializeResult) {
760
+ const userAgent = isRecord3(initializeResult) ? asString(initializeResult["userAgent"]) : null;
761
+ return userAgent?.match(/\/(\S+)/)?.[1] ?? null;
762
+ }
758
763
  function decodeThreadOpen(result) {
759
764
  const thread = isRecord3(result) ? isRecord3(result["thread"]) ? result["thread"] : result : null;
760
765
  const id = thread ? asString(thread["id"]) : null;
@@ -992,7 +997,15 @@ async function createCodexRpcClient(handle, handlers) {
992
997
  const settled = new Promise((resolve2, reject) => {
993
998
  pending.set(id, { resolve: resolve2, reject, method });
994
999
  });
995
- await writeLine({ id, method, ...params === void 0 ? {} : { params } });
1000
+ try {
1001
+ await Promise.race([
1002
+ writeLine({ id, method, ...params === void 0 ? {} : { params } }),
1003
+ settled
1004
+ ]);
1005
+ } catch (error) {
1006
+ pending.delete(id);
1007
+ throw error;
1008
+ }
996
1009
  const limit = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
997
1010
  if (limit <= 0) return await settled;
998
1011
  let timer;
@@ -1033,7 +1046,15 @@ async function createCodexRpcClient(handle, handlers) {
1033
1046
  failAll("the client was closed");
1034
1047
  await Promise.all([pumpStdout, pumpStderr]);
1035
1048
  };
1036
- return { request, notify, respond, respondError, close, pid: handle.pid };
1049
+ return {
1050
+ request,
1051
+ notify,
1052
+ respond,
1053
+ respondError,
1054
+ close,
1055
+ pid: handle.pid,
1056
+ pendingCountForTests: () => pending.size
1057
+ };
1037
1058
  }
1038
1059
 
1039
1060
  // src/approvalGrant.ts
@@ -1339,6 +1360,20 @@ function toTurnStatus(status) {
1339
1360
  return "completed";
1340
1361
  }
1341
1362
  }
1363
+ var COLLAB_CHILD_STATUSES = /* @__PURE__ */ new Set([
1364
+ "running",
1365
+ "idle",
1366
+ "failed",
1367
+ "interrupted",
1368
+ "cancelled"
1369
+ ]);
1370
+ function asCollabChildStatus(value) {
1371
+ return typeof value === "string" && COLLAB_CHILD_STATUSES.has(value) ? value : void 0;
1372
+ }
1373
+ function collabTurnEndStatus(turnStatus) {
1374
+ const state = toTurnStatus(turnStatus);
1375
+ return state === "completed" ? "idle" : state;
1376
+ }
1342
1377
  function threadStateFromStatus(status) {
1343
1378
  const type = isRecord3(status) ? asString(status["type"]) : asString(status);
1344
1379
  if (type === "idle") return "idle";
@@ -1561,11 +1596,12 @@ function mapCollabAgentEvent(input) {
1561
1596
  ];
1562
1597
  }
1563
1598
  if (method === "collabAgent/completed" || method === "task.completed") {
1599
+ const status = collabTurnEndStatus(asString(input.params["turnStatus"]) ?? void 0);
1564
1600
  return [
1565
1601
  baseEvent({
1566
1602
  type: "task.updated",
1567
1603
  threadId,
1568
- payload: { taskId: agentThreadId, status: "idle", ...linkage },
1604
+ payload: { taskId: agentThreadId, status, ...linkage },
1569
1605
  method,
1570
1606
  providerInstanceId: input.providerInstanceId
1571
1607
  })
@@ -1584,6 +1620,19 @@ function mapCollabAgentEvent(input) {
1584
1620
  })
1585
1621
  ];
1586
1622
  }
1623
+ if (method === "collabAgent/metadata") {
1624
+ const status = asCollabChildStatus(input.params["status"]);
1625
+ if (status === void 0) return [];
1626
+ return [
1627
+ baseEvent({
1628
+ type: "task.updated",
1629
+ threadId,
1630
+ payload: { taskId: agentThreadId, status, ...linkage },
1631
+ method,
1632
+ providerInstanceId: input.providerInstanceId
1633
+ })
1634
+ ];
1635
+ }
1587
1636
  if (method === "collabAgent/tokenUsage") {
1588
1637
  const tokenUsage = isRecord3(input.params["tokenUsage"]) ? input.params["tokenUsage"] : void 0;
1589
1638
  const total = tokenUsage && isRecord3(tokenUsage["total"]) ? tokenUsage["total"] : void 0;
@@ -2336,11 +2385,25 @@ function isRootChild(agentPath, agentThreadId, rootThreadId) {
2336
2385
  if (agentThreadId === rootThreadId) return true;
2337
2386
  return agentPath === "/root" || agentPath === "/";
2338
2387
  }
2388
+ function readSubAgentActivity(method, params) {
2389
+ if (method !== "item/started" && method !== "item/completed") return void 0;
2390
+ if (itemTypeOf(params) !== "subAgentActivity") return void 0;
2391
+ const item = isRecord3(params) ? isRecord3(params["item"]) ? params["item"] : params : {};
2392
+ return {
2393
+ agentThreadId: asString(item["agentThreadId"]) ?? void 0,
2394
+ agentPath: asString(item["agentPath"]) ?? void 0
2395
+ };
2396
+ }
2339
2397
  function pathLeaf2(value) {
2340
2398
  if (!value) return void 0;
2341
2399
  const parts = value.split("/").filter((part) => part.length > 0);
2342
2400
  return parts.at(-1);
2343
2401
  }
2402
+ function unconfirmedAnswerError(requestId, delivery) {
2403
+ return new Error(
2404
+ delivery === "closed" ? `could not confirm that codex received the answer to request ${requestId}: the session closed before the write was confirmed` : `could not confirm that codex received the answer to request ${requestId}: writing it to the CLI failed`
2405
+ );
2406
+ }
2344
2407
  var CodexSessionRuntime = class {
2345
2408
  threadId;
2346
2409
  cwd;
@@ -2379,6 +2442,15 @@ var CodexSessionRuntime = class {
2379
2442
  codexNativeModeFor(this.runtimeMode, this.nativeModeId)
2380
2443
  );
2381
2444
  }
2445
+ /** 给 CLI 的应答写入失败:带上线程与方法名记一行 warn。 */
2446
+ #warnAnswerWriteFailed(method, jsonRpcId, error) {
2447
+ this.host.log.warn("writing an answer to codex failed", {
2448
+ threadId: this.threadId,
2449
+ method,
2450
+ jsonRpcId,
2451
+ error: error instanceof Error ? error.message : String(error)
2452
+ });
2453
+ }
2382
2454
  constructor(host, rpc, emit, input, cwd, appServerArgs, grants, declineRelay) {
2383
2455
  this.host = host;
2384
2456
  this.rpc = rpc;
@@ -2473,6 +2545,10 @@ var CodexSessionRuntime = class {
2473
2545
  return;
2474
2546
  }
2475
2547
  }
2548
+ const activity = readSubAgentActivity(method, params);
2549
+ if (activity?.agentThreadId !== void 0 && !isRootChild(activity.agentPath, activity.agentThreadId, this.nativeThreadId ?? this.threadId)) {
2550
+ this.upsertCollabChild(activity.agentThreadId, { agentPath: activity.agentPath });
2551
+ }
2476
2552
  this.dispatchMapped(method, params);
2477
2553
  }
2478
2554
  dispatchMapped(method, params) {
@@ -2513,23 +2589,19 @@ var CodexSessionRuntime = class {
2513
2589
  }
2514
2590
  }
2515
2591
  interceptCollab(method, params, conversationId) {
2516
- const source = isRecord3(params) ? params["source"] : void 0;
2592
+ const thread = isRecord3(params) && isRecord3(params["thread"]) ? params["thread"] : void 0;
2593
+ const source = thread === void 0 ? void 0 : thread["source"];
2517
2594
  const subAgent = isRecord3(source) ? source["subAgent"] : void 0;
2518
2595
  const spawn = isRecord3(subAgent) ? subAgent["thread_spawn"] : void 0;
2519
- if (method === "thread/started" && isRecord3(spawn)) {
2596
+ if (method === "thread/started" && thread !== void 0 && isRecord3(spawn)) {
2520
2597
  const agentPath = asString(spawn["agent_path"]) ?? void 0;
2521
- if (isRootChild(agentPath, conversationId, this.nativeThreadId ?? this.threadId)) return;
2522
- const existing = this.collabChildren.get(conversationId);
2523
- const spawnTurnId = existing?.spawnTurnId ?? this.activeTurnId;
2524
- const child2 = {
2525
- agentThreadId: conversationId,
2526
- ...agentPath ? { agentPath } : {},
2527
- ...asString(spawn["agent_role"]) ? { role: asString(spawn["agent_role"]) } : {},
2528
- ...asString(spawn["agent_nickname"]) ? { nickname: asString(spawn["agent_nickname"]) } : {},
2529
- ...spawnTurnId ? { spawnTurnId } : {}
2530
- };
2531
- this.collabChildren.set(conversationId, child2);
2532
- this.emitCollab("collabAgent/started", child2);
2598
+ const knownPath = agentPath ?? this.collabChildren.get(conversationId)?.agentPath;
2599
+ if (isRootChild(knownPath, conversationId, this.nativeThreadId ?? this.threadId)) return;
2600
+ this.upsertCollabChild(conversationId, {
2601
+ agentPath,
2602
+ role: asString(spawn["agent_role"]) ?? asString(thread["agentRole"]) ?? void 0,
2603
+ nickname: asString(spawn["agent_nickname"]) ?? asString(thread["agentNickname"]) ?? void 0
2604
+ });
2533
2605
  return;
2534
2606
  }
2535
2607
  const itemType = itemTypeOf(params);
@@ -2539,21 +2611,13 @@ var CodexSessionRuntime = class {
2539
2611
  if (receiver && this.activeTurnId) this.collabReceiverTurns.set(receiver, this.activeTurnId);
2540
2612
  return;
2541
2613
  }
2542
- if ((method === "item/started" || method === "item/completed") && itemType === "subAgentActivity") {
2543
- const item = isRecord3(params) ? isRecord3(params["item"]) ? params["item"] : params : {};
2544
- const agentThreadId = asString(item["agentThreadId"]) ?? conversationId;
2545
- const agentPath = asString(item["agentPath"]) ?? void 0;
2546
- if (isRootChild(agentPath, agentThreadId, this.nativeThreadId ?? this.threadId)) return;
2547
- if (!this.collabChildren.has(agentThreadId)) {
2548
- const spawnTurnId = this.activeTurnId;
2549
- const child2 = {
2550
- agentThreadId,
2551
- ...agentPath ? { agentPath } : {},
2552
- ...spawnTurnId ? { spawnTurnId } : {}
2553
- };
2554
- this.collabChildren.set(agentThreadId, child2);
2555
- this.emitCollab("collabAgent/started", child2);
2614
+ const activity = readSubAgentActivity(method, params);
2615
+ if (activity !== void 0) {
2616
+ const agentThreadId = activity.agentThreadId ?? conversationId;
2617
+ if (isRootChild(activity.agentPath, agentThreadId, this.nativeThreadId ?? this.threadId)) {
2618
+ return;
2556
2619
  }
2620
+ this.upsertCollabChild(agentThreadId, { agentPath: activity.agentPath });
2557
2621
  }
2558
2622
  const child = this.collabChildren.get(conversationId);
2559
2623
  if (method === "turn/started") {
@@ -2567,13 +2631,26 @@ var CodexSessionRuntime = class {
2567
2631
  if (CHILD_CHATTER_METHODS.has(method) || !CHILD_AGENT_EVENT_METHODS.has(method)) return;
2568
2632
  return;
2569
2633
  }
2634
+ if (method === "turn/started") {
2635
+ child.status = "running";
2636
+ this.emitCollab("collabAgent/statusChanged", child, { status: "running" });
2637
+ return;
2638
+ }
2570
2639
  if (method === "turn/completed") {
2571
- this.emitCollab("collabAgent/completed", child);
2640
+ const turn = isRecord3(params) && isRecord3(params["turn"]) ? params["turn"] : void 0;
2641
+ const turnStatus = turn === void 0 ? void 0 : asString(turn["status"]) ?? void 0;
2642
+ child.status = collabTurnEndStatus(turnStatus);
2643
+ this.emitCollab(
2644
+ "collabAgent/completed",
2645
+ child,
2646
+ turnStatus === void 0 ? {} : { turnStatus }
2647
+ );
2572
2648
  return;
2573
2649
  }
2574
2650
  if (method === "error") {
2575
2651
  const willRetry = isRecord3(params) ? params["willRetry"] === true : false;
2576
2652
  if (willRetry) return;
2653
+ child.status = "failed";
2577
2654
  this.emitCollab("collabAgent/statusChanged", child, { status: "systemError" });
2578
2655
  return;
2579
2656
  }
@@ -2586,6 +2663,44 @@ var CodexSessionRuntime = class {
2586
2663
  this.emitCollab("collabAgent/progress", child, params);
2587
2664
  }
2588
2665
  }
2666
+ /**
2667
+ * 两条登记路(根线程的 subAgentActivity、子线程的 thread/started)都走这里。
2668
+ * 第一次见到就登记并宣布;已登记的只合并身份:已有的字段保留,缺的补上,补到了就发
2669
+ * 一条带当前状态的元数据更新。不能再宣布一次:一轮结束之后才到的宣布,会让宿主把
2670
+ * idle 当成新一轮开始。
2671
+ */
2672
+ upsertCollabChild(agentThreadId, identity) {
2673
+ const fill = (known, next) => known ?? (next !== void 0 && next.length > 0 ? next : void 0);
2674
+ const existing = this.collabChildren.get(agentThreadId);
2675
+ const agentPath = fill(existing?.agentPath, identity.agentPath);
2676
+ const role = fill(existing?.role, identity.role);
2677
+ const nickname = fill(existing?.nickname, identity.nickname);
2678
+ if (existing === void 0) {
2679
+ const spawnTurnId = this.activeTurnId;
2680
+ const child = {
2681
+ agentThreadId,
2682
+ ...agentPath ? { agentPath } : {},
2683
+ ...role ? { role } : {},
2684
+ ...nickname ? { nickname } : {},
2685
+ ...spawnTurnId ? { spawnTurnId } : {},
2686
+ status: "running"
2687
+ };
2688
+ this.collabChildren.set(agentThreadId, child);
2689
+ this.emitCollab("collabAgent/started", child);
2690
+ return;
2691
+ }
2692
+ if (agentPath === existing.agentPath && role === existing.role && nickname === existing.nickname) {
2693
+ return;
2694
+ }
2695
+ const merged = {
2696
+ ...existing,
2697
+ ...agentPath ? { agentPath } : {},
2698
+ ...role ? { role } : {},
2699
+ ...nickname ? { nickname } : {}
2700
+ };
2701
+ this.collabChildren.set(agentThreadId, merged);
2702
+ this.emitCollab("collabAgent/metadata", merged, { status: merged.status });
2703
+ }
2589
2704
  emitCollab(method, child, extra) {
2590
2705
  const params = {
2591
2706
  agentThreadId: child.agentThreadId,
@@ -2648,7 +2763,7 @@ var CodexSessionRuntime = class {
2648
2763
  jsonRpcId: id,
2649
2764
  settle: (result) => {
2650
2765
  this.pendingUserInputs.delete(requestId);
2651
- void this.rpc.respond(id, result).finally(resolve2);
2766
+ void this.rpc.respond(id, result).catch((error) => this.#warnAnswerWriteFailed(method, id, error)).finally(resolve2);
2652
2767
  }
2653
2768
  });
2654
2769
  for (const event of events) this.emit(event);
@@ -2682,7 +2797,7 @@ var CodexSessionRuntime = class {
2682
2797
  identity,
2683
2798
  settle: (decision) => {
2684
2799
  this.pendingApprovals.delete(requestId);
2685
- void this.rpc.respond(id, decision).finally(resolve2);
2800
+ void this.rpc.respond(id, decision).catch((error) => this.#warnAnswerWriteFailed(method, id, error)).finally(resolve2);
2686
2801
  }
2687
2802
  });
2688
2803
  for (const event of events) this.emit(event);
@@ -2704,7 +2819,7 @@ var CodexSessionRuntime = class {
2704
2819
  }
2705
2820
  const ack = this.registerWriteAck(pending.jsonRpcId);
2706
2821
  pending.settle(wire);
2707
- await ack.catch(() => "closed");
2822
+ const delivery = await ack.catch(() => "closed");
2708
2823
  this.emit({
2709
2824
  eventId: `codex-req-${requestId}`,
2710
2825
  provider: CODEX_DRIVER_KIND,
@@ -2719,6 +2834,7 @@ var CodexSessionRuntime = class {
2719
2834
  ...reason ? { reason } : {}
2720
2835
  }
2721
2836
  });
2837
+ if (delivery !== "written") throw unconfirmedAnswerError(requestId, delivery);
2722
2838
  }
2723
2839
  async respondToUserInput(requestId, answers) {
2724
2840
  const pending = this.pendingUserInputs.get(requestId);
@@ -2727,7 +2843,9 @@ var CodexSessionRuntime = class {
2727
2843
  if (mapped === void 0) {
2728
2844
  throw new Error(`invalid user input answers for request ${requestId}`);
2729
2845
  }
2846
+ const ack = this.registerWriteAck(pending.jsonRpcId);
2730
2847
  pending.settle({ answers: mapped });
2848
+ const delivery = await ack.catch(() => "closed");
2731
2849
  this.emit({
2732
2850
  eventId: `codex-ui-${requestId}`,
2733
2851
  provider: CODEX_DRIVER_KIND,
@@ -2738,6 +2856,7 @@ var CodexSessionRuntime = class {
2738
2856
  // 契约的 answers 是 questionId → 答案 的 record,不是数组。
2739
2857
  payload: { answers: toCanonicalUserInputAnswers(mapped) }
2740
2858
  });
2859
+ if (delivery !== "written") throw unconfirmedAnswerError(requestId, delivery);
2741
2860
  }
2742
2861
  async withActiveWriterRecovery(run, allowUnsubscribe) {
2743
2862
  let lastError;
@@ -3539,15 +3658,18 @@ async function verifyCodexSignIn(input) {
3539
3658
  onServerRequest: () => void 0,
3540
3659
  onStderrLine: () => void 0
3541
3660
  });
3661
+ let version = null;
3542
3662
  try {
3543
- await rpc.request("initialize", CODEX_INITIALIZE_PARAMS, 15e3);
3663
+ version = codexVersionFromInitialize(
3664
+ await rpc.request("initialize", CODEX_INITIALIZE_PARAMS, 15e3)
3665
+ );
3544
3666
  await rpc.notify("initialized");
3545
3667
  const account = await rpc.request("account/read", { refreshToken: true }, 15e3);
3546
3668
  const type = isRecord3(account) ? asString(account["type"]) : null;
3547
3669
  if (type !== "chatgpt") {
3548
3670
  return {
3549
3671
  installed: true,
3550
- version: null,
3672
+ version,
3551
3673
  readiness: "unchecked",
3552
3674
  auth: { status: "unauthenticated" },
3553
3675
  ...CODEX_NATIVE_MODE_REPORT
@@ -3556,7 +3678,7 @@ async function verifyCodexSignIn(input) {
3556
3678
  const models = await listCodexModels(rpc);
3557
3679
  return {
3558
3680
  installed: true,
3559
- version: null,
3681
+ version,
3560
3682
  readiness: "ready",
3561
3683
  auth,
3562
3684
  ...models === void 0 ? {} : { models },
@@ -3565,7 +3687,7 @@ async function verifyCodexSignIn(input) {
3565
3687
  } catch {
3566
3688
  return {
3567
3689
  installed: true,
3568
- version: null,
3690
+ version,
3569
3691
  readiness: "unchecked",
3570
3692
  auth: { status: "unknown" },
3571
3693
  ...CODEX_NATIVE_MODE_REPORT
@@ -4101,7 +4223,7 @@ var createCodexInstance = (config, host) => {
4101
4223
  return booked;
4102
4224
  };
4103
4225
  const probeAuth = () => accountToAuth2(readCodexAccount(accountHomeFromLayout(layoutFor(recipe))));
4104
- const probeModels = async () => {
4226
+ const probeAppServer = async (input) => {
4105
4227
  const layout = layoutFor(recipe);
4106
4228
  const env = buildCodexSpawnEnv({
4107
4229
  recipe,
@@ -4110,6 +4232,7 @@ var createCodexInstance = (config, host) => {
4110
4232
  });
4111
4233
  let handle;
4112
4234
  let rpc;
4235
+ let version = null;
4113
4236
  try {
4114
4237
  handle = await host.process.spawn({
4115
4238
  program: recipe.binaryPath,
@@ -4123,11 +4246,14 @@ var createCodexInstance = (config, host) => {
4123
4246
  onServerRequest: () => void 0,
4124
4247
  onStderrLine: () => void 0
4125
4248
  });
4126
- await rpc.request("initialize", CODEX_INITIALIZE_PARAMS);
4249
+ version = codexVersionFromInitialize(
4250
+ await rpc.request("initialize", CODEX_INITIALIZE_PARAMS)
4251
+ );
4127
4252
  await rpc.notify("initialized");
4128
- return await listCodexModels(rpc);
4129
- } catch {
4130
- return void 0;
4253
+ return { version, models: input.listModels ? await listCodexModels(rpc) : void 0 };
4254
+ } catch (error) {
4255
+ if (error instanceof ExecutorSpawnRefusedError) throw error;
4256
+ return { version, models: void 0 };
4131
4257
  } finally {
4132
4258
  await rpc?.close().catch(() => void 0);
4133
4259
  await handle?.kill("SIGTERM").catch(() => void 0);
@@ -4154,20 +4280,20 @@ var createCodexInstance = (config, host) => {
4154
4280
  };
4155
4281
  }
4156
4282
  const connectionError = codexApiConnectionError(recipe, recipe.environment);
4283
+ const { version, models } = await probeAppServer({ listModels: connectionError === null });
4157
4284
  if (connectionError) {
4158
4285
  return {
4159
4286
  installed: true,
4160
- version: null,
4287
+ version,
4161
4288
  readiness: "error",
4162
4289
  auth: probeAuth(),
4163
4290
  detail: connectionError,
4164
4291
  ...CODEX_NATIVE_MODE_REPORT
4165
4292
  };
4166
4293
  }
4167
- const models = await probeModels();
4168
4294
  return {
4169
4295
  installed: true,
4170
- version: null,
4296
+ version,
4171
4297
  readiness: models === void 0 ? "unchecked" : "ready",
4172
4298
  auth: probeAuth(),
4173
4299
  ...models === void 0 ? {} : { models },
@@ -4219,7 +4345,13 @@ var createCodexInstance = (config, host) => {
4219
4345
  runtime?.handleNotification(notification.method, notification.params);
4220
4346
  },
4221
4347
  onServerRequest: (request) => {
4222
- void runtime?.handleServerRequest(request.id, request.method, request.params);
4348
+ void runtime?.handleServerRequest(request.id, request.method, request.params).catch((error) => {
4349
+ host.log.warn("codex server request was not answered", {
4350
+ threadId: input.threadId,
4351
+ method: request.method,
4352
+ error: error instanceof Error ? error.message : String(error)
4353
+ });
4354
+ });
4223
4355
  },
4224
4356
  onStderrLine: (line) => {
4225
4357
  runtime?.handleStderrLine(line);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-codex",
3
- "version": "0.2.2130",
3
+ "version": "0.2.2147",
4
4
  "description": "Codex executor: Codex CLI over the app-server JSON-RPC protocol.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -20,7 +20,7 @@
20
20
  "@types/node": "24.12.4",
21
21
  "esbuild": "0.28.1",
22
22
  "vite-plus": "0.2.2",
23
- "@ycodium-ai/plugin-api": "0.2.2130"
23
+ "@ycodium-ai/plugin-api": "0.2.0"
24
24
  },
25
25
  "ycodium": {
26
26
  "plugin": "./dist/index.js",