@ai-sdk/harness-opencode 1.0.88 → 1.0.92

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.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @ai-sdk/harness-opencode
2
2
 
3
+ ## 1.0.92
4
+
5
+ ### Patch Changes
6
+
7
+ - eccb89e: fix(harness-opencode): authorize host tools and resolve permissions for task-linked subagents.
8
+ - @ai-sdk/harness@1.0.91
9
+
10
+ ## 1.0.91
11
+
12
+ ### Patch Changes
13
+
14
+ - 0e590d2: feat(harness): harden credential brokering to only apply with correct ephemeral secret
15
+ - Updated dependencies [3e125ba]
16
+ - Updated dependencies [0e590d2]
17
+ - @ai-sdk/provider-utils@5.0.32
18
+ - @ai-sdk/harness@1.0.90
19
+
20
+ ## 1.0.90
21
+
22
+ ### Patch Changes
23
+
24
+ - @ai-sdk/harness@1.0.89
25
+
26
+ ## 1.0.89
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [32349cc]
31
+ - Updated dependencies [a9782e1]
32
+ - Updated dependencies [35841f5]
33
+ - Updated dependencies [d2f3353]
34
+ - @ai-sdk/harness@1.0.88
35
+ - @ai-sdk/provider-utils@5.0.31
36
+
3
37
  ## 1.0.88
4
38
 
5
39
  ### Patch Changes
@@ -666,6 +666,11 @@ function getOpenCodeEventSessionId(event) {
666
666
  if (event.type?.startsWith("session.") && typeof props.id === "string") {
667
667
  return props.id;
668
668
  }
669
+ const info = asOpenCodeObject(props.info);
670
+ if (typeof info?.sessionID === "string") return info.sessionID;
671
+ if ((event.type === "session.created" || event.type === "session.updated" || event.type === "session.deleted") && typeof info?.id === "string") {
672
+ return info.id;
673
+ }
669
674
  const part = props.part;
670
675
  const partObject = asOpenCodeObject(part);
671
676
  if (typeof partObject?.sessionID === "string") return partObject.sessionID;
@@ -973,6 +978,7 @@ function createEmitStreamEvent({
973
978
  nativeNameField: nativeNameField2,
974
979
  getHostToolName: getHostToolName2,
975
980
  authorizeHostToolCall: authorizeHostToolCall2,
981
+ onSubagentSession,
976
982
  isMcpToolName,
977
983
  stripWorkDir: stripWorkDir2,
978
984
  formatError: formatError2
@@ -1004,6 +1010,7 @@ function createEmitStreamEvent({
1004
1010
  nativeNameField: nativeNameField2,
1005
1011
  getHostToolName: getHostToolName2,
1006
1012
  authorizeHostToolCall: authorizeHostToolCall2,
1013
+ onSubagentSession,
1007
1014
  isMcpToolName
1008
1015
  });
1009
1016
  return;
@@ -1252,6 +1259,7 @@ function emitLegacyToolPart({
1252
1259
  nativeNameField: nativeNameField2,
1253
1260
  getHostToolName: getHostToolName2,
1254
1261
  authorizeHostToolCall: authorizeHostToolCall2,
1262
+ onSubagentSession,
1255
1263
  isMcpToolName
1256
1264
  }) {
1257
1265
  const toolPart = legacyToolPartFromValue(part);
@@ -1264,6 +1272,17 @@ function emitLegacyToolPart({
1264
1272
  const rawToolName = toolPart.tool;
1265
1273
  if (rawToolName === "StructuredOutput") return;
1266
1274
  const toolName = toWireToolName2(rawToolName);
1275
+ if (toolName === "agent") {
1276
+ const metadata = {
1277
+ ...toolPart.metadata ?? {},
1278
+ ...toolPart.state?.metadata ?? {}
1279
+ };
1280
+ const parentSessionId = stringValue2(metadata.parentSessionId);
1281
+ const sessionId = stringValue2(metadata.sessionId);
1282
+ if (parentSessionId && sessionId) {
1283
+ onSubagentSession?.({ parentSessionId, sessionId });
1284
+ }
1285
+ }
1267
1286
  state.toolNames.set(callID, { rawToolName, toolName });
1268
1287
  const hostToolName = getHostToolName2(toolName, rawToolName);
1269
1288
  if (hostToolName) {
@@ -2262,6 +2281,15 @@ async function consumeEvents({
2262
2281
  const stream = await subscribeLegacyEvents({ client, signal });
2263
2282
  onSubscribed?.();
2264
2283
  if (!stream) return;
2284
+ const taskSessionIds = /* @__PURE__ */ new Set([sessionId]);
2285
+ const registerSubagentSession = (sourceSessionId) => function register({
2286
+ parentSessionId,
2287
+ sessionId: subagentSessionId
2288
+ }) {
2289
+ if (parentSessionId === sourceSessionId && taskSessionIds.has(sourceSessionId)) {
2290
+ taskSessionIds.add(subagentSessionId);
2291
+ }
2292
+ };
2265
2293
  const emitStreamEvent = createEmitStreamEvent({
2266
2294
  state,
2267
2295
  emit,
@@ -2271,19 +2299,46 @@ async function consumeEvents({
2271
2299
  nativeNameField,
2272
2300
  getHostToolName,
2273
2301
  authorizeHostToolCall: (input) => authorizeHostToolCall({ ...input, state }),
2302
+ onSubagentSession: registerSubagentSession(sessionId),
2274
2303
  isMcpToolName: (toolName) => [...runtime.mcpToolPrefixes].some((prefix) => toolName.startsWith(prefix)),
2275
2304
  stripWorkDir,
2276
2305
  formatError
2277
2306
  });
2307
+ const descendantEventProcessors = /* @__PURE__ */ new Map();
2308
+ const processDescendantEvent = (descendantSessionId, event) => {
2309
+ let processEvent = descendantEventProcessors.get(descendantSessionId);
2310
+ if (!processEvent) {
2311
+ const descendantState = createTranslationState();
2312
+ processEvent = createEmitStreamEvent({
2313
+ state: descendantState,
2314
+ emit: () => void 0,
2315
+ emitWarning: () => void 0,
2316
+ emitError: () => void 0,
2317
+ toWireToolName,
2318
+ nativeNameField,
2319
+ getHostToolName,
2320
+ authorizeHostToolCall: (input) => authorizeHostToolCall({ ...input, state: descendantState }),
2321
+ onSubagentSession: registerSubagentSession(descendantSessionId),
2322
+ isMcpToolName: () => false,
2323
+ stripWorkDir,
2324
+ formatError
2325
+ });
2326
+ descendantEventProcessors.set(descendantSessionId, processEvent);
2327
+ }
2328
+ processEvent(event);
2329
+ };
2278
2330
  for await (const rawEvent of stream) {
2279
2331
  if (signal.aborted || turn.abortSignal.aborted) break;
2280
2332
  const event = unwrapOpenCodeEvent(rawEvent);
2281
2333
  const eventSessionId = event ? getOpenCodeEventSessionId(event) : void 0;
2282
- if (!event || eventSessionId && eventSessionId !== sessionId) continue;
2334
+ if (!event) continue;
2335
+ const scopedSessionId = !eventSessionId || eventSessionId === sessionId ? sessionId : taskSessionIds.has(eventSessionId) ? eventSessionId : void 0;
2336
+ if (!scopedSessionId) continue;
2337
+ const isDescendant = scopedSessionId !== sessionId;
2283
2338
  if (event.type === "permission.v2.asked") {
2284
2339
  await handlePermissionV2({
2285
2340
  client,
2286
- sessionId,
2341
+ sessionId: scopedSessionId,
2287
2342
  permissionMode,
2288
2343
  builtinToolFiltering,
2289
2344
  turn,
@@ -2293,16 +2348,19 @@ async function consumeEvents({
2293
2348
  } else if (event.type === "permission.asked") {
2294
2349
  await handlePermission({
2295
2350
  client,
2296
- sessionId,
2351
+ sessionId: scopedSessionId,
2297
2352
  permissionMode,
2298
2353
  builtinToolFiltering,
2299
2354
  turn,
2300
2355
  emit,
2301
2356
  event
2302
2357
  });
2358
+ } else if (isDescendant) {
2359
+ processDescendantEvent(scopedSessionId, event);
2303
2360
  } else {
2304
2361
  emitStreamEvent(event);
2305
2362
  }
2363
+ if (isDescendant) continue;
2306
2364
  if (onEvent?.(event)) break;
2307
2365
  }
2308
2366
  }