mio-agent-runtime 0.3.1 → 0.3.2

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/observe/observer.js +39 -5
  2. package/package.json +24 -24
@@ -74,10 +74,11 @@ function loadState(home) {
74
74
  files: parsed.files || {},
75
75
  buffers: parsed.buffers || {},
76
76
  openTurns: parsed.openTurns || {},
77
+ contexts: parsed.contexts || {},
77
78
  }
78
79
  }
79
80
  } catch (_) {}
80
- return { version: 1, files: {}, buffers: {}, openTurns: {} }
81
+ return { version: 1, files: {}, buffers: {}, openTurns: {}, contexts: {} }
81
82
  }
82
83
 
83
84
  function saveState(home, state) {
@@ -221,6 +222,34 @@ function feedWorkbuddyLine(turn, obj) {
221
222
  return { finalized: finalized, next: turn }
222
223
  }
223
224
 
225
+ const CONTEXT_BEGIN = '<!-- MIO_CONTEXT_BEGIN -->'
226
+ const CONTEXT_END = '<!-- MIO_CONTEXT_END -->'
227
+ const CONTEXT_MAX = 6
228
+
229
+ // Maintain a compact 'recent Mio context' block inside <workspace>/AGENTS.md,
230
+ // which WorkBuddy's MemoryLoader auto-injects into every session. This makes
231
+ // retrieval guaranteed (not dependent on the model deciding to read memory).
232
+ function updateProjectContext(state, cwd, line) {
233
+ if (!cwd || !line) return
234
+ const target = path.join(cwd, 'AGENTS.md')
235
+ const list = state.contexts[cwd] || []
236
+ list.unshift(line)
237
+ if (list.length > CONTEXT_MAX) list.pop()
238
+ state.contexts[cwd] = list
239
+ try {
240
+ let content = fs.existsSync(target) ? fs.readFileSync(target, 'utf8') : ''
241
+ const block = CONTEXT_BEGIN + '\n## Mio 最近上下文(自动注入)\n' + list.map(function (l) { return '- ' + l }).join('\n') + '\n' + CONTEXT_END
242
+ const start = content.indexOf(CONTEXT_BEGIN)
243
+ if (start !== -1) {
244
+ const end = content.indexOf(CONTEXT_END, start)
245
+ content = end === -1 ? content.slice(0, start) : content.slice(0, start) + content.slice(end + CONTEXT_END.length)
246
+ }
247
+ content = content.trimEnd() + '\n\n' + block + '\n'
248
+ fs.mkdirSync(path.dirname(target), { recursive: true })
249
+ fs.writeFileSync(target, content, 'utf8')
250
+ } catch (_) {}
251
+ }
252
+
224
253
  function localDateKey(ts) {
225
254
  const d = new Date(Number(ts) || Date.now())
226
255
  const y = d.getFullYear()
@@ -247,7 +276,7 @@ function writeWorkbuddyDigest(turn, outcome, summary) {
247
276
  } catch (_) {}
248
277
  }
249
278
 
250
- function emitWorkbuddyOutcome(turn, sinks) {
279
+ function emitWorkbuddyOutcome(turn, sinks, state) {
251
280
  const la = turn.lastAssistant
252
281
  if (!la) return false
253
282
  let outcome
@@ -277,7 +306,10 @@ function emitWorkbuddyOutcome(turn, sinks) {
277
306
  project: turn.project,
278
307
  })
279
308
 
280
- if (outcome === 'success' && summary.length >= 40) {
309
+ // Low threshold: even a short but real completion summary must reach the
310
+ // passive retrieval paths (memory + daily digest + AGENTS.md context block).
311
+ // 40 was too strict and silently dropped short summaries from retrieval.
312
+ if (outcome === 'success' && summary.length >= 10) {
281
313
  sinks.memory({
282
314
  kind: 'note',
283
315
  content: '[workbuddy] 任务完成: ' + summary.slice(0, 160),
@@ -286,6 +318,8 @@ function emitWorkbuddyOutcome(turn, sinks) {
286
318
  source: 'workbuddy-observer',
287
319
  })
288
320
  writeWorkbuddyDigest(turn, outcome, summary)
321
+ var ctxTime = new Date(Number(turn.ts) || Date.now()).toLocaleString('zh-CN', { hour12: false })
322
+ updateProjectContext(state, turn.cwd, ctxTime + ' | ' + outcome + ' | ' + summary.slice(0, 80))
289
323
  }
290
324
 
291
325
  for (const err of turn.errors) {
@@ -369,7 +403,7 @@ function runCycle(home, state, sinks, opts) {
369
403
  }
370
404
  const result = feedWorkbuddyLine(turn, obj)
371
405
  if (result.finalized) {
372
- if (emitWorkbuddyOutcome(result.finalized, sinks)) out.outcomes += 1
406
+ if (emitWorkbuddyOutcome(result.finalized, sinks, state)) out.outcomes += 1
373
407
  }
374
408
  turn = result.next
375
409
  }
@@ -377,7 +411,7 @@ function runCycle(home, state, sinks, opts) {
377
411
  }
378
412
 
379
413
  if (turn.lastAssistant && now - st.mtimeMs > IDLE_MS) {
380
- if (emitWorkbuddyOutcome(turn, sinks)) out.outcomes += 1
414
+ if (emitWorkbuddyOutcome(turn, sinks, state)) out.outcomes += 1
381
415
  state.openTurns[file] = null
382
416
  } else if (turn.id) {
383
417
  state.openTurns[file] = turn
package/package.json CHANGED
@@ -1,24 +1,24 @@
1
- {
2
- "name": "mio-agent-runtime",
3
- "version": "0.3.1",
4
- "description": "Mio Agent Runtime installer and MCP intelligence layer",
5
- "license": "MIT",
6
- "type": "commonjs",
7
- "bin": {
8
- "mio": "bin/mio.js"
9
- },
10
- "files": [
11
- "bin/",
12
- "server/",
13
- "adapters/",
14
- "observe/",
15
- "README.md"
16
- ],
17
- "scripts": {
18
- "check": "node --check bin/mio.js && node --check adapters/codex.js && node --check adapters/opencode.js && node --check adapters/workbuddy.js && node --check server/mio-intelligence-mcp/index.js && node --check observe/observer.js",
19
- "prepack": "npm run check"
20
- },
21
- "engines": {
22
- "node": ">=18"
23
- }
24
- }
1
+ {
2
+ "name": "mio-agent-runtime",
3
+ "version": "0.3.2",
4
+ "description": "Mio Agent Runtime installer and MCP intelligence layer",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "bin": {
8
+ "mio": "bin/mio.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "server/",
13
+ "adapters/",
14
+ "observe/",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "check": "node --check bin/mio.js && node --check adapters/codex.js && node --check adapters/opencode.js && node --check adapters/workbuddy.js && node --check server/mio-intelligence-mcp/index.js && node --check observe/observer.js",
19
+ "prepack": "npm run check"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ }
24
+ }