@agentknight/sdk 0.9.46 → 0.9.48

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,15 +1,15 @@
1
1
  import {
2
2
  latestPreviewItems
3
- } from "./chunk-QBKKQQCB.js";
3
+ } from "./chunk-6VEMXJW4.js";
4
4
  import {
5
5
  UnsupportedAgentOperationError
6
- } from "./chunk-7A2SQAZ7.js";
6
+ } from "./chunk-R5LSWHRH.js";
7
7
  import {
8
8
  ConversationItemSchema,
9
9
  InteractionRequestSchema,
10
10
  SESSION_TIMELINE_PAGE_SIZE,
11
11
  SessionSummarySchema
12
- } from "./chunk-DUMC5F2D.js";
12
+ } from "./chunk-BDKVGENQ.js";
13
13
 
14
14
  // src/codex-adapter.ts
15
15
  import { randomUUID } from "node:crypto";
@@ -300,6 +300,7 @@ var NativeItem = z3.object({
300
300
  var NativeTurn = z3.object({
301
301
  id: NativeId,
302
302
  status: z3.enum(["inProgress", "completed", "interrupted", "failed"]),
303
+ startedAt: z3.number().nullable().optional(),
303
304
  items: z3.array(NativeItem)
304
305
  });
305
306
  var ThreadResult = z3.object({
@@ -342,8 +343,8 @@ function base(threadId, turnId, nativeId) {
342
343
  sourceEventIds: [nativeId]
343
344
  };
344
345
  }
345
- function projectItem(threadId, turnId, item, completed) {
346
- const common = base(threadId, turnId, item.id);
346
+ function projectItem(threadId, turnId, item, completed, timestamp) {
347
+ const common = { ...base(threadId, turnId, item.id), ...timestamp === void 0 ? {} : { timestamp } };
347
348
  switch (item.type) {
348
349
  case "userMessage":
349
350
  return ConversationItemSchema.parse({
@@ -394,7 +395,8 @@ var StoredSession = z4.object({
394
395
  summary: SessionSummarySchema,
395
396
  modelId: z4.string(),
396
397
  items: z4.array(ConversationItemSchema),
397
- uncertain: z4.boolean()
398
+ uncertain: z4.boolean(),
399
+ native: z4.boolean().optional()
398
400
  });
399
401
  var Inventory = z4.object({
400
402
  version: z4.literal(1),
@@ -415,6 +417,8 @@ var CodexCodingAgentAdapter = class {
415
417
  #identity;
416
418
  #directory;
417
419
  #sessions = /* @__PURE__ */ new Map();
420
+ #discovered = /* @__PURE__ */ new Map();
421
+ #retiredSessions = /* @__PURE__ */ new Set();
418
422
  #pending = /* @__PURE__ */ new Map();
419
423
  #callbacks;
420
424
  #rpc;
@@ -434,6 +438,9 @@ var CodexCodingAgentAdapter = class {
434
438
  const command = options.command ?? "codex";
435
439
  if (!command.trim() || command.includes("\0")) throw new Error("Invalid Codex executable");
436
440
  this.#options = { ...options, command, args: [...options.args ?? ["app-server"]] };
441
+ if (options.nativeSessionOwner !== void 0) {
442
+ SessionSummarySchema.pick({ userId: true, machineId: true }).parse(options.nativeSessionOwner);
443
+ }
437
444
  this.#identity = hash(JSON.stringify([options.ownerId ?? "host", command, this.#options.args]));
438
445
  this.#directory = join2(resolve(options.dataDirectory), "codex", this.#identity);
439
446
  }
@@ -526,6 +533,8 @@ var CodexCodingAgentAdapter = class {
526
533
  }
527
534
  this.#rpc = void 0;
528
535
  this.#sessions.clear();
536
+ this.#discovered.clear();
537
+ this.#retiredSessions.clear();
529
538
  }
530
539
  setSessionCallbacks(callbacks) {
531
540
  this.#callbacks = callbacks;
@@ -538,13 +547,13 @@ var CodexCodingAgentAdapter = class {
538
547
  }
539
548
  #known(id, requireShared = true) {
540
549
  this.#ready();
541
- const session = this.#sessions.get(id);
550
+ const session = this.#sessions.get(id) ?? this.#discovered.get(id);
542
551
  if (!session) throw new Error("Unknown or unowned Codex session");
543
552
  if (requireShared && !session.summary.isRemote) throw new Error("Codex session is not shared");
544
553
  return session;
545
554
  }
546
555
  isSessionVisible(id) {
547
- return this.#started && this.#sessions.get(id)?.summary.isRemote === true;
556
+ return this.#started && (this.#sessions.get(id) ?? this.#discovered.get(id))?.summary.isRemote === true;
548
557
  }
549
558
  async #native() {
550
559
  this.#ready();
@@ -606,11 +615,12 @@ var CodexCodingAgentAdapter = class {
606
615
  const snapshot = JSON.stringify({
607
616
  version: 1,
608
617
  identity: this.#identity,
609
- sessions: [...this.#sessions.values()].map(({ summary, modelId, items, uncertain }) => ({
618
+ sessions: [...this.#sessions.values()].map(({ summary, modelId, items, uncertain, native }) => ({
610
619
  summary,
611
620
  modelId,
612
621
  items,
613
- uncertain
622
+ uncertain,
623
+ ...native === void 0 ? {} : { native }
614
624
  }))
615
625
  });
616
626
  const staging = join2(this.#directory, `inventory-${randomUUID()}.tmp`);
@@ -647,6 +657,11 @@ var CodexCodingAgentAdapter = class {
647
657
  }
648
658
  async listSessions(userId, machineId) {
649
659
  this.#ready();
660
+ const owner = this.#options.nativeSessionOwner;
661
+ if (owner !== void 0 && owner.userId === userId && owner.machineId === machineId) {
662
+ await this.#scanNative(owner);
663
+ return [...this.#sessions.values(), ...this.#discovered.values()].filter((session) => session.summary.userId === userId && session.summary.machineId === machineId && session.summary.isRemote).map((session) => ({ ...session.summary })).sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt));
664
+ }
650
665
  const owned = [...this.#sessions.values()].filter((s) => s.summary.userId === userId && s.summary.machineId === machineId && s.summary.isRemote);
651
666
  const rpc = this.#rpc;
652
667
  if (owned.length && rpc && !rpc.closed && !this.#opening && !this.#fatal) {
@@ -690,6 +705,79 @@ var CodexCodingAgentAdapter = class {
690
705
  (s) => s.summary.userId === userId && s.summary.machineId === machineId && s.summary.isRemote
691
706
  ).map((s) => ({ ...s.summary })).sort((a, b) => b.modifiedAt.localeCompare(a.modifiedAt));
692
707
  }
708
+ async #scanNative(owner) {
709
+ const rpc = await this.#native();
710
+ const next = /* @__PURE__ */ new Map();
711
+ const seen = /* @__PURE__ */ new Set();
712
+ const present = /* @__PURE__ */ new Set();
713
+ let cursor = null;
714
+ do {
715
+ const result = z4.object({
716
+ data: z4.array(z4.object({
717
+ id: NativeId,
718
+ name: z4.string().nullable().optional(),
719
+ preview: z4.string(),
720
+ cwd: z4.string(),
721
+ createdAt: z4.number(),
722
+ updatedAt: z4.number(),
723
+ model: z4.string().nullable().optional()
724
+ })),
725
+ nextCursor: z4.string().nullable()
726
+ }).parse(await rpc.request("thread/list", { cursor, limit: 100, sortKey: "updated_at", useStateDbOnly: true }));
727
+ this.#ready();
728
+ for (const entry of result.data) {
729
+ present.add(entry.id);
730
+ this.#retiredSessions.delete(entry.id);
731
+ const existing = this.#sessions.get(entry.id) ?? this.#discovered.get(entry.id);
732
+ if (existing && (existing.summary.userId !== owner.userId || existing.summary.machineId !== owner.machineId)) {
733
+ throw new Error("Codex native thread belongs to another PC owner");
734
+ }
735
+ const summary = SessionSummarySchema.parse({
736
+ ...owner,
737
+ sessionId: entry.id,
738
+ summary: (entry.name || entry.preview).slice(0, 4096),
739
+ workingDirectory: entry.cwd,
740
+ createdAt: new Date(entry.createdAt * 1e3).toISOString(),
741
+ modifiedAt: new Date(entry.updatedAt * 1e3).toISOString(),
742
+ isRemote: existing?.summary.isRemote ?? true,
743
+ renameSupported: false
744
+ });
745
+ if (existing) {
746
+ existing.summary = summary;
747
+ if (!this.#sessions.has(entry.id)) next.set(entry.id, existing);
748
+ } else {
749
+ next.set(entry.id, this.#runtime({
750
+ summary,
751
+ modelId: entry.model || CODEX_DEFAULT_MODEL_ID,
752
+ items: [],
753
+ uncertain: false,
754
+ native: true
755
+ }));
756
+ }
757
+ }
758
+ cursor = result.nextCursor;
759
+ if (cursor !== null) {
760
+ if (seen.has(cursor) || seen.size >= 100) throw new Error("Codex native thread pagination did not terminate");
761
+ seen.add(cursor);
762
+ }
763
+ } while (cursor !== null);
764
+ for (const id of this.#discovered.keys()) {
765
+ if (!next.has(id) && !this.#sessions.has(id)) this.#retiredSessions.add(id);
766
+ }
767
+ this.#discovered.clear();
768
+ for (const [id, session] of next) {
769
+ if (!this.#sessions.has(id)) this.#discovered.set(id, session);
770
+ }
771
+ let removed = false;
772
+ for (const [id, session] of this.#sessions) {
773
+ if (session.native && !present.has(id) && !session.active && !session.sending && !session.queue.length && !session.uncertain && !session.aborting && this.#operations === 0) {
774
+ this.#sessions.delete(id);
775
+ this.#retiredSessions.add(id);
776
+ removed = true;
777
+ }
778
+ }
779
+ if (removed) await this.#save();
780
+ }
693
781
  async listModels(sessionId) {
694
782
  if (sessionId) this.#known(sessionId);
695
783
  this.#operations++;
@@ -798,12 +886,18 @@ var CodexCodingAgentAdapter = class {
798
886
  async setSessionRemote(id, enabled) {
799
887
  const session = this.#known(id, false);
800
888
  session.summary.isRemote = enabled;
889
+ if (this.#discovered.has(id)) {
890
+ this.#sessions.set(id, session);
891
+ this.#discovered.delete(id);
892
+ }
801
893
  if (!enabled) await this.#abort(session);
802
894
  await this.#save();
803
895
  this.#events?.onSessionInventoryChanged(id);
804
896
  return this.getSessionRemoteStatus(id);
805
897
  }
806
- async watchSession(id, _watched) {
898
+ async watchSession(id, watched) {
899
+ this.#ready();
900
+ if (!watched && this.#retiredSessions.has(id)) return;
807
901
  this.#known(id);
808
902
  }
809
903
  async readSessionPlan(_id) {
@@ -819,6 +913,16 @@ var CodexCodingAgentAdapter = class {
819
913
  const session = this.#known(id);
820
914
  const size = options.pageSize ?? SESSION_TIMELINE_PAGE_SIZE;
821
915
  if (!Number.isInteger(size) || size < 1 || size > SESSION_TIMELINE_PAGE_SIZE) throw new RangeError("Invalid timeline page size");
916
+ if (session.native && !session.active && !session.sending && !session.queue.length) {
917
+ await this.#locked(session, async () => {
918
+ if (session.active || session.sending || session.queue.length) return;
919
+ const rpc = await this.#native();
920
+ const result = ThreadResult.parse(await rpc.request("thread/read", { threadId: id, includeTurns: true }));
921
+ this.#known(id);
922
+ if (result.thread.id !== id) throw new Error("Codex returned history for another native thread");
923
+ this.#importHistory(session, result.thread.turns);
924
+ });
925
+ }
822
926
  let end = session.items.length;
823
927
  let cursorStatus = "ok";
824
928
  if (options.cursor !== void 0) {
@@ -835,6 +939,29 @@ var CodexCodingAgentAdapter = class {
835
939
  cursorStatus
836
940
  };
837
941
  }
942
+ #importHistory(session, turns, publish = false) {
943
+ const previous = new Map(session.items.map((item) => [item.id, item]));
944
+ const items = [];
945
+ const updates = [];
946
+ for (const turn of turns) {
947
+ const timestamp = turn.startedAt == null ? session.summary.createdAt : new Date(turn.startedAt * 1e3).toISOString();
948
+ for (const native of turn.items) {
949
+ const old = previous.get(itemId(session.summary.sessionId, native.id));
950
+ const projected = projectItem(session.summary.sessionId, turn.id, native, turn.status !== "inProgress", old?.timestamp ?? timestamp);
951
+ if (!projected) continue;
952
+ const item = { ...projected, revision: old?.revision ?? 1 };
953
+ const changed = JSON.stringify(item) !== JSON.stringify(old);
954
+ if (old && changed) item.revision++;
955
+ items.push(item);
956
+ previous.delete(item.id);
957
+ if (changed) updates.push(item);
958
+ }
959
+ }
960
+ session.items = [...items, ...[...previous.values()].filter((item) => publish || item.kind === "notice")];
961
+ if (publish && session.summary.isRemote) {
962
+ for (const item of updates) this.#events?.onConversationItem(session.summary.sessionId, structuredClone(item));
963
+ }
964
+ }
838
965
  #locked(session, run) {
839
966
  this.#operations++;
840
967
  const work = session.lock.then(run);
@@ -851,12 +978,19 @@ var CodexCodingAgentAdapter = class {
851
978
  const threadId = session.summary.sessionId;
852
979
  const read = ThreadResult.parse(await rpc.request("thread/read", { threadId, includeTurns: true }));
853
980
  if (read.thread.id !== threadId || !["idle", "notLoaded"].includes(read.thread.status.type) || read.thread.turns.some((turn) => turn.status === "inProgress")) {
854
- session.uncertain = true;
855
- await this.#save();
981
+ if (!session.native) {
982
+ session.uncertain = true;
983
+ await this.#save();
984
+ }
856
985
  throw new Error("Codex owned thread is not verifiably idle; refusing to attach");
857
986
  }
858
987
  this.#known(threadId);
859
988
  if (session.aborting) throw new Error("Codex resume cancelled");
989
+ if (session.native && this.#discovered.has(threadId)) {
990
+ this.#sessions.set(threadId, session);
991
+ this.#discovered.delete(threadId);
992
+ await this.#save();
993
+ }
860
994
  const resumed = ThreadResult.parse(await rpc.request("thread/resume", {
861
995
  threadId,
862
996
  cwd: session.summary.workingDirectory,
@@ -869,13 +1003,9 @@ var CodexCodingAgentAdapter = class {
869
1003
  await this.#save();
870
1004
  throw new Error("Codex resume did not confirm an idle owned thread");
871
1005
  }
872
- for (const turn of resumed.thread.turns) {
873
- for (const item of turn.items) {
874
- const projected = projectItem(threadId, turn.id, item, turn.status !== "inProgress");
875
- if (projected) this.#upsert(session, projected);
876
- }
877
- }
1006
+ this.#importHistory(session, resumed.thread.turns, true);
878
1007
  session.loaded = true;
1008
+ await this.#save();
879
1009
  }
880
1010
  async sendPrompt(id, prompt, mode, attachments = [], _persistInteractions = true, files = [], _operationId, persona) {
881
1011
  const session = this.#known(id);
@@ -958,6 +1088,8 @@ var CodexCodingAgentAdapter = class {
958
1088
  });
959
1089
  }
960
1090
  async abortSession(id) {
1091
+ this.#ready();
1092
+ if (this.#retiredSessions.has(id)) return;
961
1093
  await this.#abort(this.#known(id));
962
1094
  }
963
1095
  async #abort(session) {
@@ -18,25 +18,25 @@ import {
18
18
  recordTimelineSyncDiagnostic,
19
19
  resolveGitProjectIdentity,
20
20
  sanitizeGitRemoteUrl
21
- } from "./chunk-MUKGV7IE.js";
21
+ } from "./chunk-RX7VGB3T.js";
22
22
  import {
23
23
  assertMainSessionId,
24
24
  isResearchSessionId
25
- } from "./chunk-TKIZWXMQ.js";
25
+ } from "./chunk-2QHOQXOR.js";
26
26
  import {
27
27
  GroupChatError,
28
28
  GroupChatMessageSchema,
29
29
  GroupChatRuntime
30
- } from "./chunk-OPUBIQCO.js";
30
+ } from "./chunk-H6FG5CCS.js";
31
31
  import {
32
32
  isContentfulAssistant
33
- } from "./chunk-QBKKQQCB.js";
33
+ } from "./chunk-6VEMXJW4.js";
34
34
  import {
35
35
  AgentSessionRenameError,
36
36
  SessionOperationError,
37
37
  TimelinePageBudgetError,
38
38
  validateSessionName
39
- } from "./chunk-7A2SQAZ7.js";
39
+ } from "./chunk-R5LSWHRH.js";
40
40
  import {
41
41
  ConversationItemSchema,
42
42
  CopilotModelOptionSchema,
@@ -57,7 +57,7 @@ import {
57
57
  WorkbenchScheduleEntrySchema,
58
58
  WorkbenchScheduleProposalSchema,
59
59
  WorkbenchScheduleSnapshotSchema
60
- } from "./chunk-DUMC5F2D.js";
60
+ } from "./chunk-BDKVGENQ.js";
61
61
 
62
62
  // src/copilot-adapter.ts
63
63
  import { createHash as createHash4, randomUUID as randomUUID6 } from "node:crypto";
@@ -4114,7 +4114,7 @@ var GithubCopilotAdapter = class {
4114
4114
  resolveImages: (sessionId, session, normalizer, readOnly) => this.#images.resolveTimelineImageAssets(sessionId, session, normalizer, readOnly)
4115
4115
  });
4116
4116
  agentId = "copilot";
4117
- sdkVersion = "1.0.11";
4117
+ sdkVersion = "1.0.26";
4118
4118
  agentModes = ["interactive", "plan", "autopilot"];
4119
4119
  supportsReasoningEffort = true;
4120
4120
  #upgradeSessionIds = /* @__PURE__ */ new Set();
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  AgentSelectionSchema,
3
3
  assertSelectionSnapshotFits
4
- } from "./chunk-DCY33KQC.js";
4
+ } from "./chunk-YFLDTX2W.js";
5
5
  import {
6
6
  isResearchSessionId
7
- } from "./chunk-TKIZWXMQ.js";
7
+ } from "./chunk-2QHOQXOR.js";
8
8
  import {
9
9
  GroupChatError
10
- } from "./chunk-OPUBIQCO.js";
10
+ } from "./chunk-H6FG5CCS.js";
11
11
  import {
12
12
  AgentModelListingError,
13
13
  AgentSessionRenameError,
@@ -16,11 +16,11 @@ import {
16
16
  UnsupportedAgentOperationError,
17
17
  captureWorkbenchAccess,
18
18
  validateSessionName
19
- } from "./chunk-7A2SQAZ7.js";
19
+ } from "./chunk-R5LSWHRH.js";
20
20
  import {
21
21
  InteractionResponseSchema,
22
22
  SessionSummarySchema
23
- } from "./chunk-DUMC5F2D.js";
23
+ } from "./chunk-BDKVGENQ.js";
24
24
 
25
25
  // src/managed-agent-adapter.ts
26
26
  import { createHash, randomUUID } from "node:crypto";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  latestPreviewItems
3
- } from "./chunk-QBKKQQCB.js";
3
+ } from "./chunk-6VEMXJW4.js";
4
4
  import {
5
5
  AgentSessionRenameError,
6
6
  UnsupportedAgentOperationError,
7
7
  validateSessionName
8
- } from "./chunk-7A2SQAZ7.js";
8
+ } from "./chunk-R5LSWHRH.js";
9
9
  import {
10
10
  InteractionRequestSchema,
11
11
  REASONING_EFFORTS,
12
12
  SESSION_TIMELINE_PAGE_SIZE
13
- } from "./chunk-DUMC5F2D.js";
13
+ } from "./chunk-BDKVGENQ.js";
14
14
 
15
15
  // src/pi-adapter.ts
16
16
  import { createHash as createHash2, randomUUID } from "node:crypto";
@@ -113,6 +113,7 @@ var PiTimeline = class {
113
113
  return `pi:${key(`${this.sessionId}:${signature}:${index}`)}`;
114
114
  }
115
115
  #message(message, id, final) {
116
+ if (message.role === "system") return;
116
117
  const timestamp = new Date(message.timestamp).toISOString();
117
118
  if (message.role === "user") this.#turnId = id;
118
119
  if (message.role === "user" || message.role === "assistant") {
@@ -771,6 +772,7 @@ var PiCodingAgentAdapter = class {
771
772
  this.#assertOpening(sessionId);
772
773
  const cancellation = (pi) => {
773
774
  const cancelled = () => this.#stopping || this.#cancelledOpenings.has(sessionId) || this.#runtimes.get(sessionId)?.aborting === true;
775
+ pi.on("input", () => cancelled() ? { action: "handled" } : void 0);
774
776
  pi.on("session_before_compact", () => cancelled() ? { cancel: true } : void 0);
775
777
  pi.on("session_before_tree", () => cancelled() ? { cancel: true } : void 0);
776
778
  };
@@ -924,11 +926,7 @@ var PiCodingAgentAdapter = class {
924
926
  runtime.primarySource = prompt;
925
927
  return runtime.session.prompt(prompt.text, {
926
928
  expandPromptTemplates: false,
927
- source: "rpc",
928
- // PI awaits compaction/extensions before Agent.prompt; cancellation must survive preflight.
929
- preflightResult: (accepted) => {
930
- if (accepted && (runtime.aborting || this.#stopping)) throw new Error("PI prompt was aborted before execution.");
931
- }
929
+ source: "rpc"
932
930
  });
933
931
  }).catch((error) => {
934
932
  this.#error(runtime, error);
package/dist/index.d.ts CHANGED
@@ -1934,7 +1934,7 @@ declare const PeerChatResultSchema: z.ZodObject<{
1934
1934
  type PeerChatResult = z.infer<typeof PeerChatResultSchema>;
1935
1935
 
1936
1936
  type RelayRegistrationStatus = {
1937
- readonly state: "connecting" | "error";
1937
+ readonly state: "connecting" | "disconnected" | "error";
1938
1938
  readonly message: string;
1939
1939
  } | {
1940
1940
  readonly state: "registered";
@@ -1992,6 +1992,8 @@ interface Agent {
1992
1992
  readonly isStopping: boolean;
1993
1993
  readonly identityHash: string;
1994
1994
  start(): Promise<void>;
1995
+ reconnectRelay(): void;
1996
+ disconnectRelay(): void;
1995
1997
  stop(): Promise<void>;
1996
1998
  waitUntilStopped(): Promise<void>;
1997
1999
  getUpgradeStatus(): Promise<{
@@ -2006,7 +2008,7 @@ interface Agent {
2006
2008
  runPeerChat(request: PeerChatRequest, signal: AbortSignal): Promise<PeerChatResult>;
2007
2009
  setPeerChatEnabled(enabled: boolean): Promise<void>;
2008
2010
  getStatus(): Promise<{
2009
- state: "initialized" | "connecting" | "ready" | "error" | "stopped";
2011
+ state: "initialized" | "connecting" | "disconnected" | "ready" | "error" | "stopped";
2010
2012
  busy: boolean;
2011
2013
  }>;
2012
2014
  }