@ai-sdk/harness-opencode 1.0.52 → 1.0.54
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 +18 -0
- package/dist/bridge/index.mjs +125 -78
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/bridge/create-emit-stream-event.ts +114 -49
- package/src/bridge/index.ts +19 -21
- package/src/bridge/opencode-events.ts +62 -37
- package/src/bridge/opencode-finish-step.ts +14 -3
- package/src/bridge/opencode-types.ts +33 -0
- package/src/bridge/opencode-usage.ts +21 -12
- package/src/opencode-harness.ts +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ai-sdk/harness-opencode
|
|
2
2
|
|
|
3
|
+
## 1.0.54
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- bdde5d9: fix(harness): avoid placing harness bootstrap files in `/tmp` and instead use sandbox working directory
|
|
8
|
+
- Updated dependencies [5fc7da5]
|
|
9
|
+
- Updated dependencies [bdde5d9]
|
|
10
|
+
- Updated dependencies [93b2acd]
|
|
11
|
+
- @ai-sdk/provider-utils@5.0.18
|
|
12
|
+
- @ai-sdk/harness@1.0.53
|
|
13
|
+
|
|
14
|
+
## 1.0.53
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- 2d9c434: fix(harness-opencode): avoid bridge import from provider-utils and rely on more granular types
|
|
19
|
+
- @ai-sdk/harness@1.0.52
|
|
20
|
+
|
|
3
21
|
## 1.0.52
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -461,7 +461,6 @@ function serialiseError(err) {
|
|
|
461
461
|
}
|
|
462
462
|
|
|
463
463
|
// src/bridge/index.ts
|
|
464
|
-
import { isRecord as isRecord5 } from "@ai-sdk/provider-utils";
|
|
465
464
|
import { randomUUID } from "crypto";
|
|
466
465
|
import { mkdirSync } from "fs";
|
|
467
466
|
import path2 from "path";
|
|
@@ -471,8 +470,12 @@ import {
|
|
|
471
470
|
createOpencodeServer
|
|
472
471
|
} from "@opencode-ai/sdk/v2";
|
|
473
472
|
|
|
473
|
+
// src/bridge/opencode-types.ts
|
|
474
|
+
function asOpenCodeObject(value) {
|
|
475
|
+
return value != null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
476
|
+
}
|
|
477
|
+
|
|
474
478
|
// src/bridge/opencode-events.ts
|
|
475
|
-
import { isRecord } from "@ai-sdk/provider-utils";
|
|
476
479
|
function createTranslationState() {
|
|
477
480
|
return {
|
|
478
481
|
streamStarted: false,
|
|
@@ -496,29 +499,32 @@ function emitOpenCodeStreamStart({
|
|
|
496
499
|
state,
|
|
497
500
|
emit
|
|
498
501
|
}) {
|
|
499
|
-
if (state.streamStarted
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
502
|
+
if (state.streamStarted) return;
|
|
503
|
+
const message = openCodeMessageInfoFromValue(info);
|
|
504
|
+
if (!message) return;
|
|
505
|
+
if (message.role !== "assistant" && message.type !== "assistant") return;
|
|
506
|
+
const providerID = stringValue(message.providerID);
|
|
507
|
+
const modelID = stringValue(message.modelID);
|
|
503
508
|
const modelId = providerID && modelID ? `${providerID}/${modelID}` : void 0;
|
|
504
509
|
state.streamStarted = true;
|
|
505
510
|
emit({ type: "stream-start", ...modelId ? { modelId } : {} });
|
|
506
511
|
}
|
|
507
512
|
function unwrapOpenCodeEvent(rawEvent) {
|
|
508
|
-
|
|
509
|
-
|
|
513
|
+
const raw = asOpenCodeObject(rawEvent);
|
|
514
|
+
if (!raw) return void 0;
|
|
510
515
|
if (raw.type === "sync" && raw.syncEvent) {
|
|
511
|
-
const sync = raw.syncEvent;
|
|
516
|
+
const sync = asOpenCodeObject(raw.syncEvent);
|
|
517
|
+
if (!sync) return void 0;
|
|
512
518
|
return {
|
|
513
519
|
id: String(sync.id ?? raw.id ?? ""),
|
|
514
520
|
type: stripSyncVersion(String(sync.type ?? "")),
|
|
515
|
-
properties:
|
|
521
|
+
properties: openCodeEventPropertiesFromValue(sync.data) ?? {}
|
|
516
522
|
};
|
|
517
523
|
}
|
|
518
524
|
return {
|
|
519
525
|
id: typeof raw.id === "string" ? raw.id : void 0,
|
|
520
526
|
type: typeof raw.type === "string" ? stripSyncVersion(raw.type) : void 0,
|
|
521
|
-
properties:
|
|
527
|
+
properties: openCodeEventPropertiesFromValue(raw.properties) ?? openCodeEventPropertiesFromValue(raw.data) ?? {}
|
|
522
528
|
};
|
|
523
529
|
}
|
|
524
530
|
function getOpenCodeEventSessionId(event) {
|
|
@@ -530,9 +536,8 @@ function getOpenCodeEventSessionId(event) {
|
|
|
530
536
|
return props.id;
|
|
531
537
|
}
|
|
532
538
|
const part = props.part;
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
539
|
+
const partObject = asOpenCodeObject(part);
|
|
540
|
+
if (typeof partObject?.sessionID === "string") return partObject.sessionID;
|
|
536
541
|
return void 0;
|
|
537
542
|
}
|
|
538
543
|
function isStepSettlementEvent(event) {
|
|
@@ -595,17 +600,17 @@ function emitLegacyTextPartUpdate({
|
|
|
595
600
|
state,
|
|
596
601
|
emit
|
|
597
602
|
}) {
|
|
598
|
-
|
|
599
|
-
if (
|
|
600
|
-
const id = stringValue(
|
|
603
|
+
const textPart = legacyTextPartFromValue(part);
|
|
604
|
+
if (!textPart) return false;
|
|
605
|
+
const id = stringValue(textPart.id);
|
|
601
606
|
if (!id) return true;
|
|
602
|
-
const messageID = stringValue(
|
|
607
|
+
const messageID = stringValue(textPart.messageID);
|
|
603
608
|
if (messageID && state.messageRoles.get(messageID) === "user") return true;
|
|
604
|
-
const isReasoning =
|
|
609
|
+
const isReasoning = textPart.type === "reasoning";
|
|
605
610
|
const ids = isReasoning ? state.legacyReasoningPartIds : state.legacyTextPartIds;
|
|
606
611
|
const deltaMap = isReasoning ? state.reasoningDeltas : state.textDeltas;
|
|
607
612
|
const deltaType = isReasoning ? "reasoning-delta" : "text-delta";
|
|
608
|
-
const text = typeof
|
|
613
|
+
const text = typeof textPart.text === "string" ? textPart.text : void 0;
|
|
609
614
|
startLegacyPart({
|
|
610
615
|
ids,
|
|
611
616
|
id,
|
|
@@ -622,7 +627,7 @@ function emitLegacyTextPartUpdate({
|
|
|
622
627
|
});
|
|
623
628
|
deltaMap.set(id, text);
|
|
624
629
|
}
|
|
625
|
-
if (
|
|
630
|
+
if (textPart.time?.end != null) {
|
|
626
631
|
ids.delete(id);
|
|
627
632
|
deltaMap.delete(id);
|
|
628
633
|
emit({ type: isReasoning ? "reasoning-end" : "text-end", id });
|
|
@@ -632,9 +637,6 @@ function emitLegacyTextPartUpdate({
|
|
|
632
637
|
function stripSyncVersion(type) {
|
|
633
638
|
return type.replace(/\.\d+$/, "");
|
|
634
639
|
}
|
|
635
|
-
function asRecord(value) {
|
|
636
|
-
return isRecord(value) ? value : void 0;
|
|
637
|
-
}
|
|
638
640
|
function stringValue(value) {
|
|
639
641
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
640
642
|
}
|
|
@@ -654,18 +656,27 @@ function startLegacyPart({
|
|
|
654
656
|
ids.add(id);
|
|
655
657
|
emit({ type: `${type}-start`, id });
|
|
656
658
|
}
|
|
657
|
-
function
|
|
658
|
-
return
|
|
659
|
+
function openCodeMessageInfoFromValue(value) {
|
|
660
|
+
return asOpenCodeObject(value);
|
|
661
|
+
}
|
|
662
|
+
function openCodeEventPropertiesFromValue(value) {
|
|
663
|
+
return asOpenCodeObject(value);
|
|
664
|
+
}
|
|
665
|
+
function legacyTextPartFromValue(value) {
|
|
666
|
+
const part = asOpenCodeObject(value);
|
|
667
|
+
if (!part || part.type !== "text" && part.type !== "reasoning") {
|
|
668
|
+
return void 0;
|
|
669
|
+
}
|
|
670
|
+
return {
|
|
671
|
+
type: part.type,
|
|
672
|
+
id: part.id,
|
|
673
|
+
messageID: part.messageID,
|
|
674
|
+
text: part.text,
|
|
675
|
+
time: asOpenCodeObject(part.time)
|
|
676
|
+
};
|
|
659
677
|
}
|
|
660
|
-
|
|
661
|
-
// src/bridge/create-emit-stream-event.ts
|
|
662
|
-
import { isRecord as isRecord4 } from "@ai-sdk/provider-utils";
|
|
663
|
-
|
|
664
|
-
// src/bridge/opencode-finish-step.ts
|
|
665
|
-
import { isRecord as isRecord3 } from "@ai-sdk/provider-utils";
|
|
666
678
|
|
|
667
679
|
// src/bridge/opencode-usage.ts
|
|
668
|
-
import { isRecord as isRecord2 } from "@ai-sdk/provider-utils";
|
|
669
680
|
function mapUsage(tokens) {
|
|
670
681
|
const value = extractOpenCodeTokens(tokens) ?? zeroOpenCodeTokens();
|
|
671
682
|
const cacheRead = value.cache.read;
|
|
@@ -687,9 +698,9 @@ function defaultUsage() {
|
|
|
687
698
|
return mapUsage(zeroOpenCodeTokens());
|
|
688
699
|
}
|
|
689
700
|
function extractSessionTokens(value) {
|
|
690
|
-
const record =
|
|
701
|
+
const record = asOpenCodeObject(value);
|
|
691
702
|
if (!record) return void 0;
|
|
692
|
-
const tokens = extractOpenCodeTokens(record.tokens) ?? extractOpenCodeTokens(
|
|
703
|
+
const tokens = extractOpenCodeTokens(record.tokens) ?? extractOpenCodeTokens(record.info?.tokens) ?? extractOpenCodeTokens(record.data?.tokens) ?? extractOpenCodeTokens(record.data?.data?.tokens);
|
|
693
704
|
return tokens;
|
|
694
705
|
}
|
|
695
706
|
function subtractSessionTokens({
|
|
@@ -739,8 +750,8 @@ function addUsage({
|
|
|
739
750
|
};
|
|
740
751
|
}
|
|
741
752
|
function extractOpenCodeTokens(value) {
|
|
742
|
-
const record =
|
|
743
|
-
const cache =
|
|
753
|
+
const record = asOpenCodeObject(value);
|
|
754
|
+
const cache = asOpenCodeObject(record?.cache);
|
|
744
755
|
if (!record || !cache) return void 0;
|
|
745
756
|
return {
|
|
746
757
|
input: numberValue(record.input),
|
|
@@ -761,10 +772,7 @@ function zeroOpenCodeTokens() {
|
|
|
761
772
|
};
|
|
762
773
|
}
|
|
763
774
|
function asTokenGroup(value) {
|
|
764
|
-
return
|
|
765
|
-
}
|
|
766
|
-
function asRecord2(value) {
|
|
767
|
-
return isRecord2(value) ? value : void 0;
|
|
775
|
+
return asOpenCodeObject(value) ?? {};
|
|
768
776
|
}
|
|
769
777
|
function numberValue(value) {
|
|
770
778
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -792,10 +800,11 @@ function mapOpenCodeFinishReason(reason) {
|
|
|
792
800
|
if (normalized === "stop" || normalized === "end") return "stop";
|
|
793
801
|
return "other";
|
|
794
802
|
}
|
|
795
|
-
function
|
|
796
|
-
|
|
803
|
+
function translateLegacyStepFinishPart(value) {
|
|
804
|
+
const part = asOpenCodeObject(value);
|
|
805
|
+
if (!part || part.type !== "step-finish") return void 0;
|
|
797
806
|
const rawFinish = typeof part.reason === "string" ? part.reason : "stop";
|
|
798
|
-
|
|
807
|
+
const event = {
|
|
799
808
|
type: "finish-step",
|
|
800
809
|
finishReason: {
|
|
801
810
|
unified: mapOpenCodeFinishReason(rawFinish),
|
|
@@ -804,6 +813,10 @@ function legacyStepFinishPartToFinishStep(part) {
|
|
|
804
813
|
usage: mapUsage(part.tokens),
|
|
805
814
|
...typeof part.cost === "number" ? { harnessMetadata: { opencode: { cost: part.cost } } } : {}
|
|
806
815
|
};
|
|
816
|
+
return {
|
|
817
|
+
event,
|
|
818
|
+
...typeof part.id === "string" ? { partId: part.id } : {}
|
|
819
|
+
};
|
|
807
820
|
}
|
|
808
821
|
|
|
809
822
|
// src/bridge/create-emit-stream-event.ts
|
|
@@ -823,8 +836,8 @@ function createEmitStreamEvent({
|
|
|
823
836
|
const type = event.type;
|
|
824
837
|
const props = event.properties ?? {};
|
|
825
838
|
if (type === "message.updated") {
|
|
826
|
-
const info = props.info;
|
|
827
|
-
if (
|
|
839
|
+
const info = openCodeMessageInfoFromValue(props.info);
|
|
840
|
+
if (info) {
|
|
828
841
|
const id = stringValue2(info.id);
|
|
829
842
|
const role = stringValue2(info.role);
|
|
830
843
|
if (id && role) state.messageRoles.set(id, role);
|
|
@@ -994,7 +1007,7 @@ function createEmitStreamEvent({
|
|
|
994
1007
|
}
|
|
995
1008
|
if (type === "session.next.retried") {
|
|
996
1009
|
const error = props.error ?? event;
|
|
997
|
-
if (
|
|
1010
|
+
if (openCodeErrorFromValue(error)?.isRetryable === false) {
|
|
998
1011
|
emitError({
|
|
999
1012
|
error,
|
|
1000
1013
|
message: "OpenCode session retry failed"
|
|
@@ -1068,9 +1081,9 @@ function emitLegacyStepFinishPart({
|
|
|
1068
1081
|
state,
|
|
1069
1082
|
emit
|
|
1070
1083
|
}) {
|
|
1071
|
-
const
|
|
1072
|
-
if (!
|
|
1073
|
-
const
|
|
1084
|
+
const translated = translateLegacyStepFinishPart(part);
|
|
1085
|
+
if (!translated) return false;
|
|
1086
|
+
const { event, partId: id } = translated;
|
|
1074
1087
|
if (id) {
|
|
1075
1088
|
if (state.legacyStepFinishPartIds.has(id)) return true;
|
|
1076
1089
|
state.legacyStepFinishPartIds.add(id);
|
|
@@ -1089,16 +1102,12 @@ function emitLegacyToolPart({
|
|
|
1089
1102
|
getHostToolName: getHostToolName2,
|
|
1090
1103
|
authorizeHostToolCall: authorizeHostToolCall2
|
|
1091
1104
|
}) {
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
const status = legacyToolPartStatus(toolPart);
|
|
1105
|
+
const toolPart = legacyToolPartFromValue(part);
|
|
1106
|
+
if (!toolPart) return;
|
|
1107
|
+
const status = toolPart.status;
|
|
1096
1108
|
if (status !== "running" && status !== "completed" && status !== "error") {
|
|
1097
1109
|
return;
|
|
1098
1110
|
}
|
|
1099
|
-
if (typeof toolPart.tool !== "string" || typeof toolPart.callID !== "string") {
|
|
1100
|
-
return;
|
|
1101
|
-
}
|
|
1102
1111
|
const callID = toolPart.callID;
|
|
1103
1112
|
const rawToolName = toolPart.tool;
|
|
1104
1113
|
const toolName = toWireToolName2(rawToolName);
|
|
@@ -1123,7 +1132,7 @@ function emitLegacyToolPart({
|
|
|
1123
1132
|
...nativeNameField2({ nativeName: rawToolName, toolName }),
|
|
1124
1133
|
input: JSON.stringify(legacyToolPartInput(toolPart)),
|
|
1125
1134
|
providerExecuted: true,
|
|
1126
|
-
...toolPart.
|
|
1135
|
+
...toolPart.providerMetadata ? { providerMetadata: toolPart.providerMetadata } : {}
|
|
1127
1136
|
});
|
|
1128
1137
|
}
|
|
1129
1138
|
if ((status === "completed" || status === "error") && !state.toolResultsEmitted.has(callID)) {
|
|
@@ -1137,19 +1146,15 @@ function emitLegacyToolPart({
|
|
|
1137
1146
|
});
|
|
1138
1147
|
}
|
|
1139
1148
|
}
|
|
1140
|
-
function legacyToolPartStatus(part) {
|
|
1141
|
-
return typeof part.state === "string" ? part.state : typeof part.state === "object" && part.state !== null ? String(part.state.status ?? "") : void 0;
|
|
1142
|
-
}
|
|
1143
1149
|
function legacyToolPartInput(part) {
|
|
1144
|
-
const state = typeof part.state === "object" && part.state !== null ? part.state : void 0;
|
|
1145
1150
|
return {
|
|
1146
|
-
...
|
|
1147
|
-
...
|
|
1148
|
-
...
|
|
1151
|
+
...part.metadata ?? {},
|
|
1152
|
+
...part.state?.metadata ?? {},
|
|
1153
|
+
...part.state?.input ?? {}
|
|
1149
1154
|
};
|
|
1150
1155
|
}
|
|
1151
1156
|
function legacyToolPartOutput(part) {
|
|
1152
|
-
const state =
|
|
1157
|
+
const state = part.state;
|
|
1153
1158
|
if (state?.status === "error") {
|
|
1154
1159
|
return state.error ?? part.error ?? state.result ?? "tool failed";
|
|
1155
1160
|
}
|
|
@@ -1174,9 +1179,10 @@ function nextRetryEventMessage({
|
|
|
1174
1179
|
details.push(`attempt ${props.attempt}`);
|
|
1175
1180
|
}
|
|
1176
1181
|
const error = props.error;
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
const
|
|
1182
|
+
const errorDetails = openCodeErrorFromValue(error);
|
|
1183
|
+
if (errorDetails) {
|
|
1184
|
+
const message = stringValue2(errorDetails.message) ?? stringValue2(errorDetails.data?.message);
|
|
1185
|
+
const statusCode = errorDetails.statusCode;
|
|
1180
1186
|
if (typeof statusCode === "number") {
|
|
1181
1187
|
details.push(`HTTP ${statusCode}`);
|
|
1182
1188
|
}
|
|
@@ -1189,6 +1195,45 @@ function nextRetryEventMessage({
|
|
|
1189
1195
|
function stringValue2(value) {
|
|
1190
1196
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1191
1197
|
}
|
|
1198
|
+
function legacyToolPartFromValue(value) {
|
|
1199
|
+
const part = asOpenCodeObject(value);
|
|
1200
|
+
if (!part || part.type !== "tool" || typeof part.tool !== "string" || typeof part.callID !== "string") {
|
|
1201
|
+
return void 0;
|
|
1202
|
+
}
|
|
1203
|
+
const stateObject = asOpenCodeObject(part.state);
|
|
1204
|
+
const provider = asOpenCodeObject(part.provider);
|
|
1205
|
+
const state = stateObject ? {
|
|
1206
|
+
status: stringValue2(stateObject.status),
|
|
1207
|
+
input: asOpenCodeObject(stateObject.input),
|
|
1208
|
+
metadata: asOpenCodeObject(stateObject.metadata),
|
|
1209
|
+
output: stateObject.output,
|
|
1210
|
+
result: stateObject.result,
|
|
1211
|
+
structured: stateObject.structured,
|
|
1212
|
+
content: stateObject.content,
|
|
1213
|
+
error: stateObject.error
|
|
1214
|
+
} : void 0;
|
|
1215
|
+
return {
|
|
1216
|
+
type: "tool",
|
|
1217
|
+
callID: part.callID,
|
|
1218
|
+
tool: part.tool,
|
|
1219
|
+
status: typeof part.state === "string" ? part.state : state?.status ?? void 0,
|
|
1220
|
+
state,
|
|
1221
|
+
metadata: asOpenCodeObject(part.metadata),
|
|
1222
|
+
providerMetadata: provider?.metadata,
|
|
1223
|
+
error: part.error
|
|
1224
|
+
};
|
|
1225
|
+
}
|
|
1226
|
+
function openCodeErrorFromValue(value) {
|
|
1227
|
+
const error = asOpenCodeObject(value);
|
|
1228
|
+
if (!error) return void 0;
|
|
1229
|
+
const data = asOpenCodeObject(error.data);
|
|
1230
|
+
return {
|
|
1231
|
+
isRetryable: error.isRetryable,
|
|
1232
|
+
message: error.message,
|
|
1233
|
+
statusCode: error.statusCode,
|
|
1234
|
+
data: data ? { message: data.message } : void 0
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1192
1237
|
|
|
1193
1238
|
// src/bridge/opencode-path.ts
|
|
1194
1239
|
import path from "path";
|
|
@@ -2022,7 +2067,7 @@ async function handlePermissionV2({
|
|
|
2022
2067
|
action: String(props.action ?? ""),
|
|
2023
2068
|
resources: Array.isArray(props.resources) ? props.resources.map(String) : [],
|
|
2024
2069
|
requestID,
|
|
2025
|
-
toolCallId:
|
|
2070
|
+
toolCallId: String(props.source?.callID ?? requestID),
|
|
2026
2071
|
permissionMode,
|
|
2027
2072
|
builtinToolFiltering,
|
|
2028
2073
|
turn,
|
|
@@ -2047,11 +2092,12 @@ async function handlePermission({
|
|
|
2047
2092
|
const props = event.properties ?? {};
|
|
2048
2093
|
const requestID = String(props.id ?? "");
|
|
2049
2094
|
if (!requestID) return;
|
|
2095
|
+
const tool = asOpenCodeObject(props.tool);
|
|
2050
2096
|
const reply = await selectPermissionReply({
|
|
2051
2097
|
action: String(props.permission ?? ""),
|
|
2052
2098
|
resources: Array.isArray(props.patterns) ? props.patterns.map(String) : [],
|
|
2053
2099
|
requestID,
|
|
2054
|
-
toolCallId:
|
|
2100
|
+
toolCallId: String(tool?.callID ?? requestID),
|
|
2055
2101
|
permissionMode,
|
|
2056
2102
|
builtinToolFiltering,
|
|
2057
2103
|
turn,
|
|
@@ -2317,14 +2363,12 @@ function modelRefFromAssistantSnapshot(assistant) {
|
|
|
2317
2363
|
if (model) return model;
|
|
2318
2364
|
const direct = modelRefFromValue(assistant);
|
|
2319
2365
|
if (direct) return direct;
|
|
2320
|
-
|
|
2321
|
-
return modelRefFromValue(assistant.metadata.assistant);
|
|
2322
|
-
}
|
|
2323
|
-
return void 0;
|
|
2366
|
+
return modelRefFromValue(asOpenCodeObject(assistant.metadata)?.assistant);
|
|
2324
2367
|
}
|
|
2325
2368
|
function modelRefFromSessionInfo(data) {
|
|
2326
|
-
|
|
2327
|
-
|
|
2369
|
+
const session = asOpenCodeObject(data);
|
|
2370
|
+
if (!session) return void 0;
|
|
2371
|
+
return modelRefFromValue(session.model) ?? modelRefFromObject(session);
|
|
2328
2372
|
}
|
|
2329
2373
|
function modelRefFromStart(start) {
|
|
2330
2374
|
const model = splitModel(start.model, start.provider);
|
|
@@ -2335,7 +2379,10 @@ function modelRefFromStart(start) {
|
|
|
2335
2379
|
};
|
|
2336
2380
|
}
|
|
2337
2381
|
function modelRefFromValue(value) {
|
|
2338
|
-
|
|
2382
|
+
const model = asOpenCodeObject(value);
|
|
2383
|
+
return model ? modelRefFromObject(model) : void 0;
|
|
2384
|
+
}
|
|
2385
|
+
function modelRefFromObject(value) {
|
|
2339
2386
|
const providerID = stringValue2(value.providerID);
|
|
2340
2387
|
const modelID = stringValue2(value.modelID ?? value.id);
|
|
2341
2388
|
if (!providerID || !modelID) return void 0;
|