heyio 0.1.21 → 0.1.23

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,3 +1,4 @@
1
+ import crypto from "node:crypto";
1
2
  import { approveAll, } from "@github/copilot-sdk";
2
3
  import { config } from "../config.js";
3
4
  import { SESSIONS_DIR } from "../paths.js";
@@ -21,6 +22,7 @@ const HEALTH_CHECK_INTERVAL_MS = 30_000;
21
22
  const SEND_TIMEOUT_MS = 600_000;
22
23
  const MAX_RETRIES = 3;
23
24
  const SESSION_ID_KEY = "orchestrator_session_id";
25
+ const SESSION_TOOLS_KEY = "orchestrator_session_tools";
24
26
  // ---------------------------------------------------------------------------
25
27
  // Module state
26
28
  // ---------------------------------------------------------------------------
@@ -75,6 +77,11 @@ function getSessionConfig() {
75
77
  const tools = createTools(getToolDeps());
76
78
  return { tools, skillDirectories: getSkillDirectories() };
77
79
  }
80
+ /** Hash of tool names — used to detect when tools change across updates. */
81
+ function toolFingerprint(tools) {
82
+ const names = (tools ?? []).map((t) => t.name).sort().join(",");
83
+ return crypto.createHash("sha256").update(names).digest("hex").slice(0, 16);
84
+ }
78
85
  function buildFullSessionConfig() {
79
86
  const { tools, skillDirectories } = getSessionConfig();
80
87
  return {
@@ -97,21 +104,6 @@ function buildFullSessionConfig() {
97
104
  },
98
105
  };
99
106
  }
100
- function buildResumeConfig() {
101
- const { tools, skillDirectories } = getSessionConfig();
102
- return {
103
- configDir: SESSIONS_DIR,
104
- streaming: true,
105
- tools,
106
- skillDirectories,
107
- onPermissionRequest: approveAll,
108
- infiniteSessions: {
109
- enabled: true,
110
- backgroundCompactionThreshold: 0.80,
111
- bufferExhaustionThreshold: 0.95,
112
- },
113
- };
114
- }
115
107
  // ---------------------------------------------------------------------------
116
108
  // Error classification
117
109
  // ---------------------------------------------------------------------------
@@ -173,21 +165,45 @@ async function ensureOrchestratorSession() {
173
165
  try {
174
166
  const c = await ensureClient();
175
167
  const savedSessionId = getState(SESSION_ID_KEY);
168
+ const savedToolsHash = getState(SESSION_TOOLS_KEY);
169
+ const { tools, skillDirectories } = getSessionConfig();
170
+ const currentToolsHash = toolFingerprint(tools);
176
171
  if (savedSessionId) {
177
- try {
178
- console.error("[io] Resuming session:", savedSessionId);
179
- const session = await c.resumeSession(savedSessionId, buildResumeConfig());
180
- orchestratorSession = session;
181
- return session;
182
- }
183
- catch (err) {
184
- console.error("[io] Failed to resume session, creating new one:", err instanceof Error ? err.message : err);
172
+ if (!savedToolsHash || savedToolsHash !== currentToolsHash) {
173
+ console.error("[io] Tool set changed since last session — starting fresh");
185
174
  deleteState(SESSION_ID_KEY);
175
+ deleteState(SESSION_TOOLS_KEY);
176
+ }
177
+ else {
178
+ try {
179
+ console.error("[io] Resuming session:", savedSessionId);
180
+ const session = await c.resumeSession(savedSessionId, {
181
+ configDir: SESSIONS_DIR,
182
+ streaming: true,
183
+ tools,
184
+ skillDirectories,
185
+ onPermissionRequest: approveAll,
186
+ infiniteSessions: {
187
+ enabled: true,
188
+ backgroundCompactionThreshold: 0.80,
189
+ bufferExhaustionThreshold: 0.95,
190
+ },
191
+ });
192
+ orchestratorSession = session;
193
+ setState(SESSION_TOOLS_KEY, currentToolsHash);
194
+ return session;
195
+ }
196
+ catch (err) {
197
+ console.error("[io] Failed to resume session, creating new one:", err instanceof Error ? err.message : err);
198
+ deleteState(SESSION_ID_KEY);
199
+ deleteState(SESSION_TOOLS_KEY);
200
+ }
186
201
  }
187
202
  }
188
203
  console.error("[io] Creating new orchestrator session");
189
204
  const session = await c.createSession(buildFullSessionConfig());
190
205
  setState(SESSION_ID_KEY, session.sessionId);
206
+ setState(SESSION_TOOLS_KEY, currentToolsHash);
191
207
  orchestratorSession = session;
192
208
  return session;
193
209
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "heyio",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "IO — a personal AI assistant built on the GitHub Copilot SDK",
5
5
  "bin": {
6
6
  "io": "dist/index.js"