@ouro.bot/cli 0.1.0-alpha.89 → 0.1.0-alpha.90

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/changelog.json CHANGED
@@ -1,6 +1,13 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.90",
6
+ "changes": [
7
+ "coding_spawn now reuses the newest active matching coding session instead of blindly creating another coding-* lane for the same task, workspace, and origin thread.",
8
+ "Reused coding sessions are surfaced explicitly in the tool payload, which keeps live operator updates anchored to the real active child session instead of drifting onto stale parallel status."
9
+ ]
10
+ },
4
11
  {
5
12
  "version": "0.1.0-alpha.89",
6
13
  "changes": [
@@ -31,6 +31,35 @@ function emitCodingToolEvent(toolName) {
31
31
  meta: { toolName },
32
32
  });
33
33
  }
34
+ function sameOriginSession(left, right) {
35
+ if (!left && !right)
36
+ return true;
37
+ if (!left || !right)
38
+ return false;
39
+ return left.friendId === right.friendId && left.channel === right.channel && left.key === right.key;
40
+ }
41
+ function matchesReusableCodingSession(session, request) {
42
+ if (session.status !== "spawning" && session.status !== "running" && session.status !== "waiting_input" && session.status !== "stalled") {
43
+ return false;
44
+ }
45
+ return (session.runner === request.runner &&
46
+ session.workdir === request.workdir &&
47
+ session.taskRef === request.taskRef &&
48
+ session.scopeFile === request.scopeFile &&
49
+ session.stateFile === request.stateFile &&
50
+ session.obligationId === request.obligationId &&
51
+ sameOriginSession(request.originSession, session.originSession));
52
+ }
53
+ function latestSessionFirst(left, right) {
54
+ const lastActivityDelta = Date.parse(right.lastActivityAt) - Date.parse(left.lastActivityAt);
55
+ if (lastActivityDelta !== 0)
56
+ return lastActivityDelta;
57
+ return right.id.localeCompare(left.id);
58
+ }
59
+ function findReusableCodingSession(sessions, request) {
60
+ const matches = sessions.filter((session) => matchesReusableCodingSession(session, request)).sort(latestSessionFirst);
61
+ return matches[0] ?? null;
62
+ }
34
63
  const codingSpawnTool = {
35
64
  type: "function",
36
65
  function: {
@@ -150,6 +179,19 @@ exports.codingToolDefinitions = [
150
179
  if (stateFile)
151
180
  request.stateFile = stateFile;
152
181
  const manager = (0, index_1.getCodingSessionManager)();
182
+ const existingSession = findReusableCodingSession(manager.listSessions(), request);
183
+ if (existingSession) {
184
+ (0, runtime_1.emitNervesEvent)({
185
+ component: "repertoire",
186
+ event: "repertoire.coding_session_reused",
187
+ message: "reused active coding session",
188
+ meta: { id: existingSession.id, runner: existingSession.runner, taskRef: existingSession.taskRef },
189
+ });
190
+ if (ctx?.codingFeedback) {
191
+ (0, index_1.attachCodingSessionFeedback)(manager, existingSession, ctx.codingFeedback);
192
+ }
193
+ return JSON.stringify({ ...existingSession, reused: true });
194
+ }
153
195
  const session = await manager.spawnSession(request);
154
196
  if (session.obligationId) {
155
197
  (0, obligations_1.advanceObligation)((0, identity_1.getAgentRoot)(), session.obligationId, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.89",
3
+ "version": "0.1.0-alpha.90",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",