mio-agent-runtime 0.5.1 → 0.5.3
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/package.json
CHANGED
|
@@ -19,7 +19,8 @@ const experienceReusePath = path.join(dataDir, 'experience_reuse.jsonl')
|
|
|
19
19
|
const queryPath = path.join(dataDir, 'queries.jsonl')
|
|
20
20
|
const agentsPath = path.join(dataDir, 'agents.jsonl')
|
|
21
21
|
const subscriptionPath = path.join(dataDir, 'subscriptions.jsonl')
|
|
22
|
-
const digestStatePath = path.join(dataDir, 'digest_state.json')
|
|
22
|
+
const digestStatePath = path.join(dataDir, 'digest_state.json')
|
|
23
|
+
const ideasPath = path.join(dataDir, 'ideas.jsonl')
|
|
23
24
|
fs.mkdirSync(dataDir, { recursive: true })
|
|
24
25
|
|
|
25
26
|
const { loadPhase0, summarizePhase0, renderPhase0Markdown } = require('./phase0')
|
|
@@ -1635,6 +1636,20 @@ const TOOLS = [
|
|
|
1635
1636
|
additionalProperties: false
|
|
1636
1637
|
},
|
|
1637
1638
|
},
|
|
1639
|
+
{
|
|
1640
|
+
name: 'mio.idea.list',
|
|
1641
|
+
description: 'List previously generated ideas, optionally filtered by keyword, strategy, or time window.',
|
|
1642
|
+
inputSchema: {
|
|
1643
|
+
type: 'object',
|
|
1644
|
+
properties: {
|
|
1645
|
+
goal: { type: 'string', description: '(Optional) Filter ideas whose goal contains this keyword.' },
|
|
1646
|
+
strategy: { type: 'string', description: '(Optional) Filter by generation strategy (e.g. SCAMPER, Analogy).' },
|
|
1647
|
+
limit: { type: 'integer', description: '(Optional) Max results, default 10.', default: 10, minimum: 1 },
|
|
1648
|
+
period: { type: 'string', description: '(Optional) Time window: 24h, 7d, 30d, or all (default).' }
|
|
1649
|
+
}
|
|
1650
|
+
},
|
|
1651
|
+
},
|
|
1652
|
+
|
|
1638
1653
|
]
|
|
1639
1654
|
|
|
1640
1655
|
async function callTool(name, args = {}) {
|
|
@@ -1679,6 +1694,8 @@ async function callTool(name, args = {}) {
|
|
|
1679
1694
|
return recordTaskOutcome(args)
|
|
1680
1695
|
case 'mio.idea.generate':
|
|
1681
1696
|
return handleIdeaGenerate(args)
|
|
1697
|
+
case 'mio.idea.list':
|
|
1698
|
+
return listIdeas(args)
|
|
1682
1699
|
default:
|
|
1683
1700
|
throw new Error(`Unknown tool: ${name}`)
|
|
1684
1701
|
}
|
|
@@ -1999,6 +2016,27 @@ function recordTaskOutcome(args = {}) {
|
|
|
1999
2016
|
}
|
|
2000
2017
|
|
|
2001
2018
|
|
|
2019
|
+
function listIdeas(args = {}) {
|
|
2020
|
+
if (!fs.existsSync(ideasPath)) return { ideas: [], count: 0, total: 0 }
|
|
2021
|
+
const now = Date.now()
|
|
2022
|
+
const period = String(args.period || 'all').trim()
|
|
2023
|
+
const periodMs = period === '24h' ? 86400000 : period === '7d' ? 604800000 : period === '30d' ? 2592000000 : Infinity
|
|
2024
|
+
const cutoff = periodMs === Infinity ? 0 : now - periodMs
|
|
2025
|
+
const goalFilter = args.goal ? String(args.goal).toLowerCase() : null
|
|
2026
|
+
const strategyFilter = args.strategy ? String(args.strategy).trim().toLowerCase() : null
|
|
2027
|
+
const limit = Math.min(Math.max(Number(args.limit) || 10, 1), 50)
|
|
2028
|
+
const all = fs.readFileSync(ideasPath, 'utf8').split('\n').filter(Boolean).map(line => {
|
|
2029
|
+
try { return JSON.parse(line) } catch (_) { return null }
|
|
2030
|
+
}).filter(Boolean)
|
|
2031
|
+
const filtered = all.filter(idea => {
|
|
2032
|
+
if (cutoff && new Date(idea.generatedAt).getTime() < cutoff) return false
|
|
2033
|
+
if (goalFilter && !String(idea.goal || '').toLowerCase().includes(goalFilter)) return false
|
|
2034
|
+
if (strategyFilter && String(idea.provenance?.strategy || '').toLowerCase() !== strategyFilter) return false
|
|
2035
|
+
return true
|
|
2036
|
+
})
|
|
2037
|
+
return { ideas: filtered.slice(-limit), count: filtered.length, total: all.length }
|
|
2038
|
+
}
|
|
2039
|
+
|
|
2002
2040
|
async function handleIdeaGenerate(args = {}) {
|
|
2003
2041
|
const { goal, context = '', constraints = [], numIdeas = 3 } = args
|
|
2004
2042
|
// Memory-grounding: reuse related prior decisions/problems from Mio so ideas
|
|
@@ -2010,14 +2048,27 @@ async function handleIdeaGenerate(args = {}) {
|
|
|
2010
2048
|
} catch (e) {
|
|
2011
2049
|
related = []
|
|
2012
2050
|
}
|
|
2051
|
+
const relatedIds = related.map((r) => r.id).filter(Boolean)
|
|
2013
2052
|
const grounding = related
|
|
2014
2053
|
.filter((r) => r && (r.content || r.kind))
|
|
2015
2054
|
.map((r) => '- [' + (r.kind || 'note') + '] ' + String(r.content || '').slice(0, 240))
|
|
2016
2055
|
.join('\n')
|
|
2056
|
+
|
|
2057
|
+
// Generation strategies give diversity without exposing the mechanism to callers.
|
|
2058
|
+
const strategies = [
|
|
2059
|
+
'SCAMPER',
|
|
2060
|
+
'Analogy',
|
|
2061
|
+
'First-Principles',
|
|
2062
|
+
'Random-Stimulus',
|
|
2063
|
+
'Constraint-Inversion'
|
|
2064
|
+
]
|
|
2065
|
+
|
|
2017
2066
|
const ideas = []
|
|
2018
2067
|
for (let i = 0; i < numIdeas; i++) {
|
|
2068
|
+
const strategy = strategies[i % strategies.length]
|
|
2019
2069
|
const blocks = [
|
|
2020
2070
|
'Goal: ' + goal,
|
|
2071
|
+
'Strategy: ' + strategy,
|
|
2021
2072
|
context ? 'Context: ' + context : '',
|
|
2022
2073
|
constraints.length ? 'Constraints: ' + constraints.join(', ') : '',
|
|
2023
2074
|
related.length
|
|
@@ -2027,10 +2078,24 @@ async function handleIdeaGenerate(args = {}) {
|
|
|
2027
2078
|
].filter(Boolean)
|
|
2028
2079
|
ideas.push({
|
|
2029
2080
|
id: 'idea_' + Date.now() + '_' + i,
|
|
2030
|
-
title: 'Idea #' + (i + 1) + ': ' + goal,
|
|
2031
|
-
description: blocks.join('\n\n')
|
|
2081
|
+
title: 'Idea #' + (i + 1) + ' (' + strategy + '): ' + goal,
|
|
2082
|
+
description: blocks.join('\n\n'),
|
|
2083
|
+
provenance: {
|
|
2084
|
+
strategy: strategy,
|
|
2085
|
+
relatedMemoryIds: relatedIds
|
|
2086
|
+
}
|
|
2032
2087
|
})
|
|
2033
2088
|
}
|
|
2089
|
+
for (const idea of ideas) {
|
|
2090
|
+
try {
|
|
2091
|
+
fs.appendFileSync(ideasPath, JSON.stringify({ id: idea.id, title: idea.title, description: idea.description, provenance: idea.provenance, goal, context: context || null, constraints, generatedAt: idea.generatedAt }) + '\n')
|
|
2092
|
+
} catch (_) {}
|
|
2093
|
+
}
|
|
2094
|
+
for (const idea of ideas) {
|
|
2095
|
+
try {
|
|
2096
|
+
fs.appendFileSync(ideasPath, JSON.stringify({ id: idea.id, title: idea.title, description: idea.description, provenance: idea.provenance, goal, context: context || null, constraints, generatedAt: idea.generatedAt }) + '\n')
|
|
2097
|
+
} catch (_) {}
|
|
2098
|
+
}
|
|
2034
2099
|
return {
|
|
2035
2100
|
ideas: ideas,
|
|
2036
2101
|
generatedAt: new Date().toISOString(),
|