@agfpd/iapeer 0.4.125 → 0.4.126
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
|
@@ -108,6 +108,9 @@ export const opencodeAdapter: RuntimeAdapter = {
|
|
|
108
108
|
const warnings = hasExplicitModel(config)
|
|
109
109
|
? []
|
|
110
110
|
: [`opencode-implicit-provider: no explicit "model" in ${p.config} — OpenCode's own default provider receives the doctrine and messages`]
|
|
111
|
+
// Handed to the plugin too, so they reach runtime.ready / state.json / fleet runtimes[].warnings like
|
|
112
|
+
// the self-check findings (not only lifecycle.log).
|
|
113
|
+
if (warnings.length) out.IAPEER_OPENCODE_WARNINGS = JSON.stringify(warnings)
|
|
111
114
|
return { env: out, readyToken: launchID, warnings }
|
|
112
115
|
},
|
|
113
116
|
|
package/src/launch/index.ts
CHANGED
|
@@ -194,13 +194,17 @@ export const launch: LaunchFn = async (
|
|
|
194
194
|
// Structural runtimes (opencode) prepare launch artifacts + extra env BEFORE spawn. The identity
|
|
195
195
|
// ABI stays authoritative: prepared env never overrides PEER_PERSONALITY/RUNTIME/IDENTITY.
|
|
196
196
|
let readyToken: string | undefined
|
|
197
|
+
const loggedWarnings = new Set<string>()
|
|
197
198
|
if (adapter.prepareLaunch) {
|
|
198
199
|
try {
|
|
199
200
|
const prepared = adapter.prepareLaunch(spec, invocation.env, cfg)
|
|
200
201
|
const { PEER_PERSONALITY, PEER_RUNTIME, PEER_IDENTITY } = invocation.env
|
|
201
202
|
invocation.env = { ...invocation.env, ...prepared.env, PEER_PERSONALITY, PEER_RUNTIME, PEER_IDENTITY }
|
|
202
203
|
readyToken = prepared.readyToken
|
|
203
|
-
for (const w of prepared.warnings ?? [])
|
|
204
|
+
for (const w of prepared.warnings ?? []) {
|
|
205
|
+
loggedWarnings.add(w)
|
|
206
|
+
appendLifecycleEvent(cfg.exitLogDir, { ev: 'launch-warning', identity, warning: w }, { env })
|
|
207
|
+
}
|
|
204
208
|
} catch (e) {
|
|
205
209
|
return fail(identity, `launch preparation failed: ${e instanceof Error ? e.message : String(e)}`)
|
|
206
210
|
}
|
|
@@ -241,7 +245,9 @@ export const launch: LaunchFn = async (
|
|
|
241
245
|
if (adapter.structuralReady && readyToken) {
|
|
242
246
|
const r = await adapter.structuralReady(spec, readyToken, Date.now() + cfg.bootDeadlineSecs * 1000, () => hostSessionAlive(identity, env), env)
|
|
243
247
|
if (!r.ok) return fail(identity, `never-became-ready (structural: ${r.reason ?? 'unknown'})`)
|
|
244
|
-
for (const w of r.warnings ?? [])
|
|
248
|
+
for (const w of r.warnings ?? []) {
|
|
249
|
+
if (!loggedWarnings.has(w)) appendLifecycleEvent(cfg.exitLogDir, { ev: 'launch-warning', identity, warning: w }, { env })
|
|
250
|
+
}
|
|
245
251
|
if (firstMessage.trim().length === 0) return ready(identity)
|
|
246
252
|
if (!adapter.deliver) return fail(identity, 'structural runtime has no deliver hook')
|
|
247
253
|
const d = await adapter.deliver({ personality: spec.personality, identity }, firstMessage, env)
|
|
@@ -119,17 +119,20 @@ export function sweepInflight(stateDir: string, identity: string, deps: Inflight
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
// A session works its input in order: a FINISHED turn for a later message means every earlier one
|
|
122
|
-
// was handled too (bounds the ledger when a turn-end record is missed).
|
|
123
|
-
|
|
122
|
+
// OF THE SAME SESSION was handled too (bounds the ledger when a turn-end record is missed). Strictly
|
|
123
|
+
// per session token: a turn finished in a NEW session says nothing about a dead session's queue —
|
|
124
|
+
// that cross-session shortcut silently dropped A and B in 0.4.122 (linus OC07 regression).
|
|
125
|
+
const finishedUpTo = new Map<string, number>()
|
|
124
126
|
const finished = new Set<string>()
|
|
127
|
+
const sessionKey = (e: InflightEntry) => e.sessionToken ?? '∅'
|
|
125
128
|
for (const e of entries) {
|
|
126
129
|
if (safe(deps.completed, e, false) || (!deps.completed && safe(deps.processed, e, false))) {
|
|
127
130
|
finished.add(e.id)
|
|
128
|
-
finishedUpTo
|
|
131
|
+
finishedUpTo.set(sessionKey(e), Math.max(finishedUpTo.get(sessionKey(e)) ?? -Infinity, e.ts))
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
134
|
for (const e of entries) {
|
|
132
|
-
if (finished.has(e.id) || e.ts < finishedUpTo) continue
|
|
135
|
+
if (finished.has(e.id) || e.ts < (finishedUpTo.get(sessionKey(e)) ?? -Infinity)) continue
|
|
133
136
|
const done = safe(deps.processed, e, false)
|
|
134
137
|
if (done) {
|
|
135
138
|
// Answered but its turn did not finish: live → still working; gone → INTERRUPTED (side effects
|
|
@@ -320,6 +320,10 @@ async function server(input) {
|
|
|
320
320
|
}
|
|
321
321
|
async function selfCheck() {
|
|
322
322
|
const warnings = []
|
|
323
|
+
try {
|
|
324
|
+
const fromCore = JSON.parse(env.IAPEER_OPENCODE_WARNINGS || '[]') // launch-time facts (e.g. implicit provider)
|
|
325
|
+
if (Array.isArray(fromCore)) for (const w of fromCore) if (typeof w === 'string') warnings.push(w)
|
|
326
|
+
} catch {}
|
|
323
327
|
try {
|
|
324
328
|
const st = await client.mcp.status()
|
|
325
329
|
for (const [name, s] of Object.entries((st && st.data) || {})) {
|