opencode-graphiti 0.1.9 → 0.1.11

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 (88) hide show
  1. package/README.md +7 -1
  2. package/esm/_dnt.polyfills.d.ts +50 -0
  3. package/esm/_dnt.polyfills.d.ts.map +1 -0
  4. package/esm/_dnt.polyfills.js +37 -0
  5. package/esm/mod.d.ts +1 -0
  6. package/esm/mod.d.ts.map +1 -1
  7. package/esm/mod.js +1 -0
  8. package/esm/src/config.d.ts +10 -1
  9. package/esm/src/config.d.ts.map +1 -1
  10. package/esm/src/config.js +30 -5
  11. package/esm/src/handlers/chat.d.ts.map +1 -1
  12. package/esm/src/handlers/chat.js +51 -42
  13. package/esm/src/handlers/event.d.ts +1 -1
  14. package/esm/src/handlers/event.d.ts.map +1 -1
  15. package/esm/src/handlers/event.js +42 -46
  16. package/esm/src/handlers/messages.d.ts.map +1 -1
  17. package/esm/src/handlers/messages.js +2 -3
  18. package/esm/src/index.js +2 -2
  19. package/esm/src/services/client.d.ts +8 -0
  20. package/esm/src/services/client.d.ts.map +1 -1
  21. package/esm/src/services/client.js +44 -24
  22. package/esm/src/services/compaction.d.ts.map +1 -1
  23. package/esm/src/services/compaction.js +24 -33
  24. package/esm/src/services/constants.d.ts +7 -0
  25. package/esm/src/services/constants.d.ts.map +1 -0
  26. package/esm/src/services/constants.js +6 -0
  27. package/esm/src/services/context-limit.d.ts +1 -1
  28. package/esm/src/services/context-limit.d.ts.map +1 -1
  29. package/esm/src/services/context-limit.js +12 -14
  30. package/esm/src/services/context.d.ts +27 -7
  31. package/esm/src/services/context.d.ts.map +1 -1
  32. package/esm/src/services/context.js +34 -2
  33. package/esm/src/services/logger.js +2 -4
  34. package/esm/src/services/sdk-normalize.d.ts +55 -0
  35. package/esm/src/services/sdk-normalize.d.ts.map +1 -0
  36. package/esm/src/services/sdk-normalize.js +61 -0
  37. package/esm/src/session.d.ts +4 -2
  38. package/esm/src/session.d.ts.map +1 -1
  39. package/esm/src/session.js +38 -34
  40. package/esm/src/types/index.d.ts +13 -14
  41. package/esm/src/types/index.d.ts.map +1 -1
  42. package/esm/src/utils.d.ts +6 -0
  43. package/esm/src/utils.d.ts.map +1 -1
  44. package/esm/src/utils.js +16 -2
  45. package/package.json +1 -1
  46. package/script/_dnt.polyfills.d.ts +50 -0
  47. package/script/_dnt.polyfills.d.ts.map +1 -0
  48. package/script/_dnt.polyfills.js +38 -0
  49. package/script/mod.d.ts +1 -0
  50. package/script/mod.d.ts.map +1 -1
  51. package/script/mod.js +1 -0
  52. package/script/src/config.d.ts +10 -1
  53. package/script/src/config.d.ts.map +1 -1
  54. package/script/src/config.js +33 -5
  55. package/script/src/handlers/chat.d.ts.map +1 -1
  56. package/script/src/handlers/chat.js +49 -40
  57. package/script/src/handlers/event.d.ts +1 -1
  58. package/script/src/handlers/event.d.ts.map +1 -1
  59. package/script/src/handlers/event.js +41 -45
  60. package/script/src/handlers/messages.d.ts.map +1 -1
  61. package/script/src/handlers/messages.js +2 -3
  62. package/script/src/index.js +2 -2
  63. package/script/src/services/client.d.ts +8 -0
  64. package/script/src/services/client.d.ts.map +1 -1
  65. package/script/src/services/client.js +44 -24
  66. package/script/src/services/compaction.d.ts.map +1 -1
  67. package/script/src/services/compaction.js +24 -33
  68. package/script/src/services/constants.d.ts +7 -0
  69. package/script/src/services/constants.d.ts.map +1 -0
  70. package/script/src/services/constants.js +9 -0
  71. package/script/src/services/context-limit.d.ts +1 -1
  72. package/script/src/services/context-limit.d.ts.map +1 -1
  73. package/script/src/services/context-limit.js +13 -15
  74. package/script/src/services/context.d.ts +27 -7
  75. package/script/src/services/context.d.ts.map +1 -1
  76. package/script/src/services/context.js +36 -4
  77. package/script/src/services/logger.js +2 -4
  78. package/script/src/services/sdk-normalize.d.ts +55 -0
  79. package/script/src/services/sdk-normalize.d.ts.map +1 -0
  80. package/script/src/services/sdk-normalize.js +67 -0
  81. package/script/src/session.d.ts +4 -2
  82. package/script/src/session.d.ts.map +1 -1
  83. package/script/src/session.js +38 -34
  84. package/script/src/types/index.d.ts +13 -14
  85. package/script/src/types/index.d.ts.map +1 -1
  86. package/script/src/utils.d.ts +6 -0
  87. package/script/src/utils.d.ts.map +1 -1
  88. package/script/src/utils.js +18 -3
@@ -13,12 +13,10 @@ exports.logger = {
13
13
  console.log(PREFIX, ...args);
14
14
  },
15
15
  warn: (...args) => {
16
- if (node_process_1.default.env.GRAPHITI_DEBUG)
17
- console.warn(PREFIX, ...args);
16
+ console.warn(PREFIX, ...args);
18
17
  },
19
18
  error: (...args) => {
20
- if (node_process_1.default.env.GRAPHITI_DEBUG)
21
- console.error(PREFIX, ...args);
19
+ console.error(PREFIX, ...args);
22
20
  },
23
21
  debug: (...args) => {
24
22
  if (node_process_1.default.env.GRAPHITI_DEBUG)
@@ -0,0 +1,55 @@
1
+ import type { Part } from "@opencode-ai/sdk";
2
+ import type { GraphitiEpisode } from "../types/index.js";
3
+ /**
4
+ * Narrow type for a single SDK message entry as returned by
5
+ * `session.messages()`.
6
+ */
7
+ export type SdkMessage = {
8
+ info: {
9
+ role?: string;
10
+ id?: string;
11
+ };
12
+ parts: Part[];
13
+ };
14
+ /**
15
+ * Normalize an SDK response that may be wrapped in `{ data: … }` or returned
16
+ * directly. Returns the inner value cast to `T`, or `undefined` when the
17
+ * response is absent.
18
+ *
19
+ * This replaces the repeated `"data" in response ? (response as
20
+ * { data?: … }).data : response` pattern found in session.ts and
21
+ * context-limit.ts.
22
+ */
23
+ export declare function unwrapSdkResponse<T>(response: unknown): T | undefined;
24
+ /**
25
+ * Extract the messages array from a raw `session.messages()` response.
26
+ * Returns an empty array when the response is missing or malformed.
27
+ */
28
+ export declare function extractSdkMessages(response: unknown): SdkMessage[];
29
+ /**
30
+ * Extract the provider list from a raw `provider.list()` response.
31
+ * Returns an empty array when the response is missing or malformed.
32
+ */
33
+ export type SdkProvider = {
34
+ id?: string;
35
+ models?: SdkModel[];
36
+ };
37
+ export type SdkModel = {
38
+ id?: string;
39
+ limit?: {
40
+ context?: number;
41
+ };
42
+ };
43
+ export declare function extractSdkProviders(response: unknown): SdkProvider[];
44
+ /**
45
+ * Normalize a raw Graphiti episode object so that `sourceDescription` is
46
+ * always the canonical field regardless of whether the payload used
47
+ * camelCase (`sourceDescription`) or snake_case (`source_description`).
48
+ *
49
+ * Call this at the API boundary (e.g. inside `GraphitiClient.getEpisodes`)
50
+ * so all downstream consumers only need to read `episode.sourceDescription`.
51
+ */
52
+ export declare function normalizeEpisode(raw: GraphitiEpisode & {
53
+ source_description?: string;
54
+ }): GraphitiEpisode;
55
+ //# sourceMappingURL=sdk-normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-normalize.d.ts","sourceRoot":"","sources":["../../../src/src/services/sdk-normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAA4B,MAAM,kBAAkB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,KAAK,EAAE,IAAI,EAAE,CAAC;CACf,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,CAMrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,OAAO,GAChB,UAAU,EAAE,CAGd;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9B,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,WAAW,EAAE,CAmBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,eAAe,GAAG;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,GACA,eAAe,CAMjB"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapSdkResponse = unwrapSdkResponse;
4
+ exports.extractSdkMessages = extractSdkMessages;
5
+ exports.extractSdkProviders = extractSdkProviders;
6
+ exports.normalizeEpisode = normalizeEpisode;
7
+ /**
8
+ * Normalize an SDK response that may be wrapped in `{ data: … }` or returned
9
+ * directly. Returns the inner value cast to `T`, or `undefined` when the
10
+ * response is absent.
11
+ *
12
+ * This replaces the repeated `"data" in response ? (response as
13
+ * { data?: … }).data : response` pattern found in session.ts and
14
+ * context-limit.ts.
15
+ */
16
+ function unwrapSdkResponse(response) {
17
+ if (response == null)
18
+ return undefined;
19
+ if (typeof response === "object" && "data" in response) {
20
+ return response.data;
21
+ }
22
+ return response;
23
+ }
24
+ /**
25
+ * Extract the messages array from a raw `session.messages()` response.
26
+ * Returns an empty array when the response is missing or malformed.
27
+ */
28
+ function extractSdkMessages(response) {
29
+ const payload = unwrapSdkResponse(response);
30
+ return Array.isArray(payload) ? payload : [];
31
+ }
32
+ function extractSdkProviders(response) {
33
+ // provider.list() may return `{ providers: [...] }` directly (no data wrap).
34
+ if (response != null && typeof response === "object") {
35
+ const obj = response;
36
+ if (Array.isArray(obj["providers"])) {
37
+ return obj["providers"];
38
+ }
39
+ if ("data" in obj) {
40
+ const data = obj["data"];
41
+ if (data != null && typeof data === "object") {
42
+ const dataObj = data;
43
+ if (Array.isArray(dataObj["providers"])) {
44
+ return dataObj["providers"];
45
+ }
46
+ }
47
+ if (Array.isArray(data))
48
+ return data;
49
+ }
50
+ }
51
+ return [];
52
+ }
53
+ /**
54
+ * Normalize a raw Graphiti episode object so that `sourceDescription` is
55
+ * always the canonical field regardless of whether the payload used
56
+ * camelCase (`sourceDescription`) or snake_case (`source_description`).
57
+ *
58
+ * Call this at the API boundary (e.g. inside `GraphitiClient.getEpisodes`)
59
+ * so all downstream consumers only need to read `episode.sourceDescription`.
60
+ */
61
+ function normalizeEpisode(raw) {
62
+ const { source_description, ...rest } = raw;
63
+ return {
64
+ ...rest,
65
+ sourceDescription: rest.sourceDescription ?? source_description,
66
+ };
67
+ }
@@ -22,6 +22,8 @@ export type SessionState = {
22
22
  messageCount: number;
23
23
  /** Buffered message strings awaiting flush. */
24
24
  pendingMessages: string[];
25
+ /** Last successfully saved idle-session snapshot body. */
26
+ lastSnapshotBody?: string;
25
27
  /** Context window limit in tokens. */
26
28
  contextLimit: number;
27
29
  /** True when this session is the primary (non-subagent) session. */
@@ -41,6 +43,8 @@ export declare class SessionManager {
41
43
  private pendingAssistantMessages;
42
44
  private bufferedAssistantMessageIds;
43
45
  constructor(defaultGroupId: string, defaultUserGroupId: string, sdkClient: OpencodeClient, graphitiClient: GraphitiClient);
46
+ /** Create a default main-session state for the given group IDs. */
47
+ createDefaultState(groupId: string, userGroupId: string): SessionState;
44
48
  /** Get the current session state, if present. */
45
49
  getState(sessionId: string): SessionState | undefined;
46
50
  /** Persist session state for the given session ID. */
@@ -54,8 +58,6 @@ export declare class SessionManager {
54
58
  state: SessionState | null;
55
59
  resolved: boolean;
56
60
  }>;
57
- /** Determine whether a session is a subagent session. */
58
- isSubagentSession(sessionId: string): Promise<boolean>;
59
61
  /** Buffer partial assistant text for a streaming message. */
60
62
  bufferAssistantPart(sessionId: string, messageId: string, text: string): void;
61
63
  /** Check if an assistant message has already been finalized. */
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZjC,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,aAAa,CAAoC;IACzD,OAAO,CAAC,wBAAwB,CAG5B;IACJ,OAAO,CAAC,2BAA2B,CAAqB;gBAGrC,cAAc,EAAE,MAAM,EACtB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,cAAc,EACzB,cAAc,EAAE,cAAc;IAGjD,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIrD,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI;IAItD,gDAAgD;IAChD,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAI7D,qDAAqD;IAC/C,eAAe,CACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAsBrC,yDAAyD;IACnD,mBAAmB,CACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IA4B7D,yDAAyD;IACnD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK5D,6DAA6D;IAC7D,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,IAAI;IAKP,gEAAgE;IAChE,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAKlE;;OAEG;IACH,wBAAwB,CACtB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,IAAI;IAwCP,+EAA+E;IACzE,oBAAoB,CACxB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgFhB,iDAAiD;IACjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKlE,uCAAuC;IACvC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;YAexB,2BAA2B;CAiC1C"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/src/session.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SessionManager = void 0;
4
+ const sdk_normalize_js_1 = require("./services/sdk-normalize.js");
5
+ const constants_js_1 = require("./services/constants.js");
4
6
  const logger_js_1 = require("./services/logger.js");
5
7
  const utils_js_1 = require("./utils.js");
6
8
  /**
@@ -58,6 +60,23 @@ class SessionManager {
58
60
  value: new Set()
59
61
  });
60
62
  }
63
+ /** Create a default main-session state for the given group IDs. */
64
+ createDefaultState(groupId, userGroupId) {
65
+ return {
66
+ groupId,
67
+ userGroupId,
68
+ injectedMemories: false,
69
+ lastInjectionFactUuids: [],
70
+ cachedMemoryContext: undefined,
71
+ cachedFactUuids: undefined,
72
+ visibleFactUuids: [],
73
+ messageCount: 0,
74
+ pendingMessages: [],
75
+ lastSnapshotBody: undefined,
76
+ contextLimit: constants_js_1.DEFAULT_CONTEXT_LIMIT,
77
+ isMain: true,
78
+ };
79
+ }
61
80
  /** Get the current session state, if present. */
62
81
  getState(sessionId) {
63
82
  return this.sessions.get(sessionId);
@@ -105,28 +124,11 @@ class SessionManager {
105
124
  }
106
125
  let state = this.sessions.get(sessionId);
107
126
  if (!state) {
108
- state = {
109
- groupId: this.defaultGroupId,
110
- userGroupId: this.defaultUserGroupId,
111
- injectedMemories: false,
112
- lastInjectionFactUuids: [],
113
- cachedMemoryContext: undefined,
114
- cachedFactUuids: undefined,
115
- visibleFactUuids: [],
116
- messageCount: 0,
117
- pendingMessages: [],
118
- contextLimit: 200_000,
119
- isMain: true,
120
- };
127
+ state = this.createDefaultState(this.defaultGroupId, this.defaultUserGroupId);
121
128
  this.sessions.set(sessionId, state);
122
129
  }
123
130
  return { state, resolved: true };
124
131
  }
125
- /** Determine whether a session is a subagent session. */
126
- async isSubagentSession(sessionId) {
127
- const parentId = await this.resolveParentId(sessionId);
128
- return !!parentId;
129
- }
130
132
  /** Buffer partial assistant text for a streaming message. */
131
133
  bufferAssistantPart(sessionId, messageId, text) {
132
134
  const key = `${sessionId}:${messageId}`;
@@ -259,15 +261,24 @@ class SessionManager {
259
261
  deleteSession(sessionId) {
260
262
  this.sessions.delete(sessionId);
261
263
  this.parentIdCache.delete(sessionId);
264
+ // Collect matching keys first, then delete in a second pass to avoid
265
+ // mutating a Map/Set while iterating over its live iterator.
266
+ const prefix = `${sessionId}:`;
267
+ const pendingToDelete = [];
262
268
  for (const key of this.pendingAssistantMessages.keys()) {
263
- if (key.startsWith(`${sessionId}:`)) {
264
- this.pendingAssistantMessages.delete(key);
265
- }
269
+ if (key.startsWith(prefix))
270
+ pendingToDelete.push(key);
271
+ }
272
+ for (const key of pendingToDelete) {
273
+ this.pendingAssistantMessages.delete(key);
266
274
  }
275
+ const bufferedToDelete = [];
267
276
  for (const key of this.bufferedAssistantMessageIds) {
268
- if (key.startsWith(`${sessionId}:`)) {
269
- this.bufferedAssistantMessageIds.delete(key);
270
- }
277
+ if (key.startsWith(prefix))
278
+ bufferedToDelete.push(key);
279
+ }
280
+ for (const key of bufferedToDelete) {
281
+ this.bufferedAssistantMessageIds.delete(key);
271
282
  }
272
283
  }
273
284
  async fetchLatestAssistantMessage(sessionId) {
@@ -276,18 +287,11 @@ class SessionManager {
276
287
  path: { id: sessionId },
277
288
  query: { limit: 20 },
278
289
  });
279
- const payload = response && typeof response === "object" &&
280
- "data" in response
281
- ? response.data
282
- : response;
283
- const messages = Array.isArray(payload)
284
- ? payload
285
- : [];
290
+ const messages = (0, sdk_normalize_js_1.extractSdkMessages)(response);
286
291
  if (messages.length === 0)
287
292
  return null;
288
- const lastAssistant = [...messages]
289
- .reverse()
290
- .find((message) => message.info?.role === "assistant");
293
+ const lastAssistant = messages
294
+ .findLast((message) => message.info?.role === "assistant");
291
295
  if (!lastAssistant)
292
296
  return null;
293
297
  const text = (0, utils_js_1.extractTextFromParts)(lastAssistant.parts);
@@ -30,11 +30,6 @@ export interface GraphitiFact {
30
30
  uuid: string;
31
31
  };
32
32
  }
33
- /** Response payload containing Graphiti facts. */
34
- export interface GraphitiFactsResponse {
35
- /** List of facts from Graphiti. */
36
- facts: GraphitiFact[];
37
- }
38
33
  /** A node retrieved from the Graphiti knowledge graph. */
39
34
  export interface GraphitiNode {
40
35
  /** Unique identifier for the node. */
@@ -46,12 +41,15 @@ export interface GraphitiNode {
46
41
  /** Optional labels associated with the node. */
47
42
  labels?: string[];
48
43
  }
49
- /** Response payload containing Graphiti nodes. */
50
- export interface GraphitiNodesResponse {
51
- /** List of nodes from Graphiti. */
52
- nodes: GraphitiNode[];
53
- }
54
- /** An episode retrieved from Graphiti memory. */
44
+ /**
45
+ * An episode retrieved from Graphiti memory.
46
+ *
47
+ * `sourceDescription` is the canonical field. Raw payloads may carry either
48
+ * `sourceDescription` (camelCase) or `source_description` (snake_case); the
49
+ * boundary helper `normalizeEpisode()` in `src/services/sdk-normalize.ts`
50
+ * collapses both into `sourceDescription` so downstream consumers only need to
51
+ * check one field.
52
+ */
55
53
  export interface GraphitiEpisode {
56
54
  /** Unique identifier for the episode. */
57
55
  uuid: string;
@@ -61,10 +59,11 @@ export interface GraphitiEpisode {
61
59
  content: string;
62
60
  /** Optional episode source type. */
63
61
  source?: string;
64
- /** Optional source description for the episode. */
62
+ /**
63
+ * Canonical source description (normalized from either camelCase or
64
+ * snake_case payload). Always populated by `normalizeEpisode()`.
65
+ */
65
66
  sourceDescription?: string;
66
- /** Optional source description (snake_case payload). */
67
- source_description?: string;
68
67
  /** Optional episode creation timestamp. */
69
68
  created_at?: string;
70
69
  /** Optional labels associated with the episode. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/types/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,mCAAmC;IACnC,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/types/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,uCAAuC;IACvC,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB"}
@@ -18,4 +18,10 @@ export declare const isTextPart: (value: unknown) => value is Part & {
18
18
  * Extract and join text from OpenCode message parts.
19
19
  */
20
20
  export declare const extractTextFromParts: (parts: Part[]) => string;
21
+ /**
22
+ * Truncate `text` to at most `budget` characters without cutting mid-line.
23
+ * Prefers to break at the last newline within the budget window; falls back
24
+ * to a raw slice only when the candidate contains no newline.
25
+ */
26
+ export declare const truncateAtLineBoundary: (text: string, budget: number) => string;
21
27
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAIF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAW7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAMF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,MAKF,CAAC"}
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.extractTextFromParts = exports.isTextPart = exports.makeUserGroupId = exports.makeGroupId = void 0;
6
+ exports.truncateAtLineBoundary = exports.extractTextFromParts = exports.isTextPart = exports.makeUserGroupId = exports.makeGroupId = void 0;
7
7
  const node_os_1 = __importDefault(require("node:os"));
8
8
  const node_process_1 = __importDefault(require("node:process"));
9
9
  const getProjectName = (directory) => directory.split("/").filter(Boolean).at(-1)?.trim() || "default";
@@ -13,7 +13,8 @@ const getUserName = (home = node_os_1.default.homedir().split("/").filter(Boolea
13
13
  */
14
14
  const makeGroupId = (prefix, directory = node_process_1.default.cwd()) => {
15
15
  const projectName = getProjectName(directory);
16
- const rawGroupId = `${prefix?.concat("-")}${projectName}__main`;
16
+ const prefixPart = prefix ? `${prefix}-` : "";
17
+ const rawGroupId = `${prefixPart}${projectName}__main`;
17
18
  return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
18
19
  };
19
20
  exports.makeGroupId = makeGroupId;
@@ -23,7 +24,8 @@ exports.makeGroupId = makeGroupId;
23
24
  const makeUserGroupId = (prefix, directory = node_process_1.default.cwd()) => {
24
25
  const projectName = getProjectName(directory);
25
26
  const userName = getUserName();
26
- const rawGroupId = `${prefix?.concat("-")}${projectName}__user-${userName}`;
27
+ const prefixPart = prefix ? `${prefix}-` : "";
28
+ const rawGroupId = `${prefixPart}${projectName}__user-${userName}`;
27
29
  return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
28
30
  };
29
31
  exports.makeUserGroupId = makeUserGroupId;
@@ -43,3 +45,16 @@ exports.isTextPart = isTextPart;
43
45
  */
44
46
  const extractTextFromParts = (parts) => parts.filter(exports.isTextPart).map((part) => part.text).join(" ").trim();
45
47
  exports.extractTextFromParts = extractTextFromParts;
48
+ /**
49
+ * Truncate `text` to at most `budget` characters without cutting mid-line.
50
+ * Prefers to break at the last newline within the budget window; falls back
51
+ * to a raw slice only when the candidate contains no newline.
52
+ */
53
+ const truncateAtLineBoundary = (text, budget) => {
54
+ if (text.length <= budget)
55
+ return text;
56
+ const candidate = text.slice(0, budget);
57
+ const lastNl = candidate.lastIndexOf("\n");
58
+ return lastNl > 0 ? candidate.slice(0, lastNl) : candidate;
59
+ };
60
+ exports.truncateAtLineBoundary = truncateAtLineBoundary;