@ai-sdk/harness 1.0.92 → 1.0.94
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 +29 -0
- package/README.md +5 -1
- package/dist/agent/index.d.ts +166 -118
- package/dist/agent/index.js +399 -102
- package/dist/agent/index.js.map +1 -1
- package/dist/bridge/index.d.ts +20 -1
- package/dist/bridge/index.js +29 -5
- package/dist/bridge/index.js.map +1 -1
- package/dist/index.d.ts +142 -102
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +8 -2
- package/dist/utils/index.js +339 -33
- package/dist/utils/index.js.map +1 -1
- package/package.json +5 -5
- package/src/agent/harness-agent-session.ts +115 -7
- package/src/agent/harness-agent-settings.ts +87 -7
- package/src/agent/harness-agent.ts +328 -112
- package/src/agent/internal/lifecycle-state-validation.ts +3 -0
- package/src/agent/internal/run-prompt.ts +49 -11
- package/src/agent/internal/strip-work-dir.ts +102 -0
- package/src/agent/internal/translate-stream-part.ts +5 -0
- package/src/bridge/index.ts +73 -6
- package/src/utils/index.ts +1 -0
- package/src/utils/write-skills.ts +419 -32
- package/src/v1/harness-v1-bridge-protocol.ts +6 -0
- package/src/v1/harness-v1-lifecycle-state.ts +45 -0
- package/src/v1/harness-v1-session.ts +3 -48
- package/src/v1/harness-v1-stream-part.ts +31 -1
- package/src/v1/index.ts +1 -0
package/dist/utils/index.js
CHANGED
|
@@ -560,7 +560,14 @@ function shellQuote(value) {
|
|
|
560
560
|
}
|
|
561
561
|
|
|
562
562
|
// src/utils/write-skills.ts
|
|
563
|
+
import { createHash } from "crypto";
|
|
563
564
|
import path2 from "path";
|
|
565
|
+
import {
|
|
566
|
+
safeParseJSON as safeParseJSON3
|
|
567
|
+
} from "@ai-sdk/provider-utils";
|
|
568
|
+
var SKILLS_MANIFEST_FILENAME = ".ai-sdk-harness-skills.json";
|
|
569
|
+
var SKILLS_MANIFEST_VERSION = 1;
|
|
570
|
+
var SAFE_MANIFEST_SKILL_NAME = /^[A-Za-z0-9._-]+$/;
|
|
564
571
|
async function writeSkills({
|
|
565
572
|
sandbox,
|
|
566
573
|
rootDir,
|
|
@@ -572,60 +579,333 @@ async function writeSkills({
|
|
|
572
579
|
invalidSkillFilePathMessage = ({ skillName, filePath }) => `Invalid skill file path for ${skillName}: ${filePath}`,
|
|
573
580
|
trailingNewline = false
|
|
574
581
|
}) {
|
|
575
|
-
var _a
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
582
|
+
var _a;
|
|
583
|
+
const projectedSkills = skills.map(
|
|
584
|
+
(skill) => projectSkill({
|
|
585
|
+
skill,
|
|
586
|
+
skillNamePattern,
|
|
587
|
+
invalidSkillNameMessage,
|
|
588
|
+
filePathMode,
|
|
589
|
+
invalidSkillFilePathMessage,
|
|
590
|
+
trailingNewline
|
|
591
|
+
})
|
|
592
|
+
).sort((a, b) => a.name.localeCompare(b.name));
|
|
593
|
+
assertUniqueSkillNames(projectedSkills);
|
|
594
|
+
const manifestPath = path2.posix.join(rootDir, SKILLS_MANIFEST_FILENAME);
|
|
595
|
+
const existingManifest = await readSkillsManifest({
|
|
596
|
+
sandbox,
|
|
597
|
+
manifestPath,
|
|
598
|
+
abortSignal
|
|
599
|
+
});
|
|
600
|
+
const nextEntries = projectedSkills.map(({ name, hash }) => ({ name, hash }));
|
|
601
|
+
const nextByName = new Map(nextEntries.map((entry) => [entry.name, entry]));
|
|
602
|
+
if ((existingManifest == null ? void 0 : existingManifest.state) === "pending") {
|
|
603
|
+
await ensureSkillsDirectory({ sandbox, rootDir, abortSignal });
|
|
604
|
+
const recoveryNames = existingManifest.skills.map((skill) => skill.name);
|
|
605
|
+
await removeSkillDirectories({
|
|
606
|
+
sandbox,
|
|
607
|
+
rootDir,
|
|
608
|
+
skillNames: recoveryNames,
|
|
609
|
+
abortSignal
|
|
610
|
+
});
|
|
611
|
+
const removed2 = recoveryNames.filter((name) => !nextByName.has(name)).sort((a, b) => a.localeCompare(b));
|
|
612
|
+
await writeProjectedSkills({
|
|
613
|
+
sandbox,
|
|
614
|
+
rootDir,
|
|
615
|
+
skills: projectedSkills,
|
|
616
|
+
abortSignal
|
|
617
|
+
});
|
|
618
|
+
await writeSkillsManifest({
|
|
619
|
+
sandbox,
|
|
620
|
+
manifestPath,
|
|
621
|
+
manifest: {
|
|
622
|
+
version: SKILLS_MANIFEST_VERSION,
|
|
623
|
+
state: "complete",
|
|
624
|
+
skills: nextEntries
|
|
625
|
+
},
|
|
626
|
+
abortSignal
|
|
627
|
+
});
|
|
628
|
+
return {
|
|
629
|
+
changed: recoveryNames.length > 0 || projectedSkills.length > 0,
|
|
630
|
+
written: projectedSkills.map((skill) => skill.name),
|
|
631
|
+
removed: removed2,
|
|
632
|
+
unchanged: []
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
const previousEntries = (_a = existingManifest == null ? void 0 : existingManifest.skills) != null ? _a : [];
|
|
636
|
+
const previousByName = new Map(
|
|
637
|
+
previousEntries.map((entry) => [entry.name, entry])
|
|
638
|
+
);
|
|
639
|
+
const removed = previousEntries.filter((entry) => !nextByName.has(entry.name)).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
|
|
640
|
+
const written = projectedSkills.filter((skill) => {
|
|
641
|
+
var _a2;
|
|
642
|
+
return ((_a2 = previousByName.get(skill.name)) == null ? void 0 : _a2.hash) !== skill.hash;
|
|
643
|
+
}).map((skill) => skill.name).sort((a, b) => a.localeCompare(b));
|
|
644
|
+
const unchanged = projectedSkills.filter((skill) => {
|
|
645
|
+
var _a2;
|
|
646
|
+
return ((_a2 = previousByName.get(skill.name)) == null ? void 0 : _a2.hash) === skill.hash;
|
|
647
|
+
}).map((skill) => skill.name).sort((a, b) => a.localeCompare(b));
|
|
648
|
+
const changed = removed.length > 0 || written.length > 0;
|
|
649
|
+
if (!changed && existingManifest != null) {
|
|
650
|
+
return { changed: false, written, removed, unchanged };
|
|
651
|
+
}
|
|
652
|
+
const previouslyOwned = new Set(previousEntries.map((entry) => entry.name));
|
|
653
|
+
for (const skillName of written) {
|
|
654
|
+
if (previouslyOwned.has(skillName)) continue;
|
|
655
|
+
await assertSkillDirectoryAvailable({
|
|
656
|
+
sandbox,
|
|
657
|
+
rootDir,
|
|
658
|
+
skillName,
|
|
659
|
+
abortSignal
|
|
581
660
|
});
|
|
582
|
-
|
|
661
|
+
}
|
|
662
|
+
await ensureSkillsDirectory({ sandbox, rootDir, abortSignal });
|
|
663
|
+
const pendingNames = Array.from(
|
|
664
|
+
/* @__PURE__ */ new Set([
|
|
665
|
+
...previousEntries.map((entry) => entry.name),
|
|
666
|
+
...nextEntries.map((entry) => entry.name)
|
|
667
|
+
])
|
|
668
|
+
).sort((a, b) => a.localeCompare(b));
|
|
669
|
+
await writeSkillsManifest({
|
|
670
|
+
sandbox,
|
|
671
|
+
manifestPath,
|
|
672
|
+
manifest: {
|
|
673
|
+
version: SKILLS_MANIFEST_VERSION,
|
|
674
|
+
state: "pending",
|
|
675
|
+
skills: pendingNames.map((name) => {
|
|
676
|
+
var _a2, _b;
|
|
677
|
+
return {
|
|
678
|
+
name,
|
|
679
|
+
hash: (_b = (_a2 = nextByName.get(name)) == null ? void 0 : _a2.hash) != null ? _b : previousByName.get(name).hash
|
|
680
|
+
};
|
|
681
|
+
})
|
|
682
|
+
},
|
|
683
|
+
abortSignal
|
|
684
|
+
});
|
|
685
|
+
await removeSkillDirectories({
|
|
686
|
+
sandbox,
|
|
687
|
+
rootDir,
|
|
688
|
+
skillNames: [
|
|
689
|
+
...removed,
|
|
690
|
+
...written.filter((name) => previouslyOwned.has(name))
|
|
691
|
+
],
|
|
692
|
+
abortSignal
|
|
693
|
+
});
|
|
694
|
+
const writtenSet = new Set(written);
|
|
695
|
+
await writeProjectedSkills({
|
|
696
|
+
sandbox,
|
|
697
|
+
rootDir,
|
|
698
|
+
skills: projectedSkills.filter((skill) => writtenSet.has(skill.name)),
|
|
699
|
+
abortSignal
|
|
700
|
+
});
|
|
701
|
+
await writeSkillsManifest({
|
|
702
|
+
sandbox,
|
|
703
|
+
manifestPath,
|
|
704
|
+
manifest: {
|
|
705
|
+
version: SKILLS_MANIFEST_VERSION,
|
|
706
|
+
state: "complete",
|
|
707
|
+
skills: nextEntries
|
|
708
|
+
},
|
|
709
|
+
abortSignal
|
|
710
|
+
});
|
|
711
|
+
return { changed, written, removed, unchanged };
|
|
712
|
+
}
|
|
713
|
+
async function ensureSkillsDirectory({
|
|
714
|
+
sandbox,
|
|
715
|
+
rootDir,
|
|
716
|
+
abortSignal
|
|
717
|
+
}) {
|
|
718
|
+
await runSandboxCommand({
|
|
719
|
+
sandbox,
|
|
720
|
+
command: `mkdir -p ${shellQuote(rootDir)}`,
|
|
721
|
+
abortSignal,
|
|
722
|
+
errorMessage: `Failed to create skills directory: ${rootDir}`
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
function projectSkill({
|
|
726
|
+
skill,
|
|
727
|
+
skillNamePattern,
|
|
728
|
+
invalidSkillNameMessage,
|
|
729
|
+
filePathMode,
|
|
730
|
+
invalidSkillFilePathMessage,
|
|
731
|
+
trailingNewline
|
|
732
|
+
}) {
|
|
733
|
+
var _a;
|
|
734
|
+
const name = validateSkillName({
|
|
735
|
+
name: skill.name,
|
|
736
|
+
pattern: skillNamePattern,
|
|
737
|
+
message: invalidSkillNameMessage
|
|
738
|
+
});
|
|
739
|
+
const files = /* @__PURE__ */ new Map();
|
|
740
|
+
files.set("SKILL.md", renderSkillFile({ skill, trailingNewline }));
|
|
741
|
+
for (const file of (_a = skill.files) != null ? _a : []) {
|
|
742
|
+
files.set(
|
|
583
743
|
normalizeSkillFilePath({
|
|
584
744
|
skillName: skill.name,
|
|
585
745
|
filePath: file.path,
|
|
586
746
|
mode: filePathMode,
|
|
587
747
|
message: invalidSkillFilePathMessage
|
|
588
|
-
})
|
|
748
|
+
}),
|
|
749
|
+
file.content
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
const projectedFiles = Array.from(files, ([filePath, content]) => ({
|
|
753
|
+
path: filePath,
|
|
754
|
+
content
|
|
755
|
+
})).sort((a, b) => a.path.localeCompare(b.path));
|
|
756
|
+
const hash = createHash("sha256");
|
|
757
|
+
for (const file of projectedFiles) {
|
|
758
|
+
hash.update(String(Buffer.byteLength(file.path)));
|
|
759
|
+
hash.update(":");
|
|
760
|
+
hash.update(file.path);
|
|
761
|
+
hash.update(String(Buffer.byteLength(file.content)));
|
|
762
|
+
hash.update(":");
|
|
763
|
+
hash.update(file.content);
|
|
764
|
+
}
|
|
765
|
+
return { name, hash: hash.digest("hex"), files: projectedFiles };
|
|
766
|
+
}
|
|
767
|
+
async function readSkillsManifest({
|
|
768
|
+
sandbox,
|
|
769
|
+
manifestPath,
|
|
770
|
+
abortSignal
|
|
771
|
+
}) {
|
|
772
|
+
const content = await sandbox.readTextFile({
|
|
773
|
+
path: manifestPath,
|
|
774
|
+
abortSignal
|
|
775
|
+
});
|
|
776
|
+
if (content == null) return void 0;
|
|
777
|
+
const parsed = await safeParseJSON3({ text: content });
|
|
778
|
+
if (!parsed.success || !isSkillsManifest(parsed.value)) {
|
|
779
|
+
throw new Error(`Invalid AI SDK harness skills manifest: ${manifestPath}`);
|
|
780
|
+
}
|
|
781
|
+
return parsed.value;
|
|
782
|
+
}
|
|
783
|
+
function isSkillsManifest(value) {
|
|
784
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
785
|
+
return false;
|
|
786
|
+
}
|
|
787
|
+
const manifest = value;
|
|
788
|
+
if (manifest.version !== SKILLS_MANIFEST_VERSION || manifest.state !== "complete" && manifest.state !== "pending" || !Array.isArray(manifest.skills)) {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
const names = /* @__PURE__ */ new Set();
|
|
792
|
+
for (const entry of manifest.skills) {
|
|
793
|
+
if (entry == null || typeof entry !== "object" || Array.isArray(entry)) {
|
|
794
|
+
return false;
|
|
589
795
|
}
|
|
796
|
+
const skill = entry;
|
|
797
|
+
if (typeof skill.name !== "string" || !isSafeManifestSkillName(skill.name) || typeof skill.hash !== "string" || !/^[a-f0-9]{64}$/.test(skill.hash) || names.has(skill.name)) {
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
names.add(skill.name);
|
|
590
801
|
}
|
|
591
|
-
|
|
592
|
-
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
async function writeSkillsManifest({
|
|
805
|
+
sandbox,
|
|
806
|
+
manifestPath,
|
|
807
|
+
manifest,
|
|
808
|
+
abortSignal
|
|
809
|
+
}) {
|
|
810
|
+
const temporaryPath = `${manifestPath}.tmp`;
|
|
811
|
+
await sandbox.writeTextFile({
|
|
812
|
+
path: temporaryPath,
|
|
813
|
+
content: `${JSON.stringify(manifest, null, 2)}
|
|
814
|
+
`,
|
|
815
|
+
abortSignal
|
|
816
|
+
});
|
|
817
|
+
await runSandboxCommand({
|
|
818
|
+
sandbox,
|
|
819
|
+
command: `mv -f ${shellQuote(temporaryPath)} ${shellQuote(manifestPath)}`,
|
|
820
|
+
abortSignal,
|
|
821
|
+
errorMessage: `Failed to update skills manifest: ${manifestPath}`
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
async function assertSkillDirectoryAvailable({
|
|
825
|
+
sandbox,
|
|
826
|
+
rootDir,
|
|
827
|
+
skillName,
|
|
828
|
+
abortSignal
|
|
829
|
+
}) {
|
|
830
|
+
const skillDir = path2.posix.join(rootDir, skillName);
|
|
831
|
+
const result = await sandbox.run({
|
|
832
|
+
command: `test ! -e ${shellQuote(skillDir)}`,
|
|
593
833
|
abortSignal
|
|
594
834
|
});
|
|
835
|
+
if (result.exitCode !== 0) {
|
|
836
|
+
throw new Error(
|
|
837
|
+
`Cannot write harness skill '${skillName}': ${skillDir} already exists and is not owned by the AI SDK harness.`
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
async function removeSkillDirectories({
|
|
842
|
+
sandbox,
|
|
843
|
+
rootDir,
|
|
844
|
+
skillNames,
|
|
845
|
+
abortSignal
|
|
846
|
+
}) {
|
|
847
|
+
if (skillNames.length === 0) return;
|
|
848
|
+
const directories = Array.from(new Set(skillNames)).sort((a, b) => a.localeCompare(b)).map((name) => shellQuote(path2.posix.join(rootDir, name))).join(" ");
|
|
849
|
+
await runSandboxCommand({
|
|
850
|
+
sandbox,
|
|
851
|
+
command: `rm -rf -- ${directories}`,
|
|
852
|
+
abortSignal,
|
|
853
|
+
errorMessage: `Failed to replace harness skills in: ${rootDir}`
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
async function writeProjectedSkills({
|
|
857
|
+
sandbox,
|
|
858
|
+
rootDir,
|
|
859
|
+
skills,
|
|
860
|
+
abortSignal
|
|
861
|
+
}) {
|
|
595
862
|
for (const skill of skills) {
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
pattern: skillNamePattern,
|
|
599
|
-
message: invalidSkillNameMessage
|
|
600
|
-
});
|
|
601
|
-
const skillDir = path2.posix.join(rootDir, name);
|
|
602
|
-
await sandbox.writeTextFile({
|
|
603
|
-
path: path2.posix.join(skillDir, "SKILL.md"),
|
|
604
|
-
content: renderSkillFile({ skill, trailingNewline }),
|
|
605
|
-
abortSignal
|
|
606
|
-
});
|
|
607
|
-
for (const file of (_b = skill.files) != null ? _b : []) {
|
|
608
|
-
const filePath = normalizeSkillFilePath({
|
|
609
|
-
skillName: skill.name,
|
|
610
|
-
filePath: file.path,
|
|
611
|
-
mode: filePathMode,
|
|
612
|
-
message: invalidSkillFilePathMessage
|
|
613
|
-
});
|
|
863
|
+
const skillDir = path2.posix.join(rootDir, skill.name);
|
|
864
|
+
for (const file of skill.files) {
|
|
614
865
|
await sandbox.writeTextFile({
|
|
615
|
-
path: path2.posix.join(skillDir,
|
|
866
|
+
path: path2.posix.join(skillDir, file.path),
|
|
616
867
|
content: file.content,
|
|
617
868
|
abortSignal
|
|
618
869
|
});
|
|
619
870
|
}
|
|
620
871
|
}
|
|
621
872
|
}
|
|
873
|
+
async function runSandboxCommand({
|
|
874
|
+
sandbox,
|
|
875
|
+
command,
|
|
876
|
+
abortSignal,
|
|
877
|
+
errorMessage
|
|
878
|
+
}) {
|
|
879
|
+
const result = await sandbox.run({ command, abortSignal });
|
|
880
|
+
if (result.exitCode !== 0) {
|
|
881
|
+
throw new Error(
|
|
882
|
+
`${errorMessage} (exit ${result.exitCode})${result.stderr ? `: ${result.stderr}` : ""}`
|
|
883
|
+
);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function assertUniqueSkillNames(skills) {
|
|
887
|
+
for (let index = 1; index < skills.length; index++) {
|
|
888
|
+
if (skills[index - 1].name === skills[index].name) {
|
|
889
|
+
throw new Error(`Duplicate skill name: ${skills[index].name}`);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
function isSafeManifestSkillName(name) {
|
|
894
|
+
SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;
|
|
895
|
+
const matches = SAFE_MANIFEST_SKILL_NAME.test(name);
|
|
896
|
+
SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;
|
|
897
|
+
return matches && name !== "." && name !== ".." && !name.includes("/");
|
|
898
|
+
}
|
|
622
899
|
function validateSkillName({
|
|
623
900
|
name,
|
|
624
901
|
pattern,
|
|
625
902
|
message
|
|
626
903
|
}) {
|
|
627
904
|
var _a;
|
|
628
|
-
|
|
905
|
+
pattern.lastIndex = 0;
|
|
906
|
+
const matches = pattern.test(name);
|
|
907
|
+
pattern.lastIndex = 0;
|
|
908
|
+
if (!matches || name === "." || name === "..") {
|
|
629
909
|
throw new Error((_a = message == null ? void 0 : message({ name })) != null ? _a : `Invalid skill name: ${name}`);
|
|
630
910
|
}
|
|
631
911
|
return name;
|
|
@@ -662,7 +942,7 @@ ${skill.content}`;
|
|
|
662
942
|
|
|
663
943
|
// src/utils/bridge-ready.ts
|
|
664
944
|
import {
|
|
665
|
-
safeParseJSON as
|
|
945
|
+
safeParseJSON as safeParseJSON4
|
|
666
946
|
} from "@ai-sdk/provider-utils";
|
|
667
947
|
import { z as z4 } from "zod/v4";
|
|
668
948
|
|
|
@@ -784,6 +1064,26 @@ var harnessV1ReasoningEndPartSchema = z2.object({
|
|
|
784
1064
|
id: z2.string(),
|
|
785
1065
|
harnessMetadata: harnessV1MetadataSchema.optional()
|
|
786
1066
|
});
|
|
1067
|
+
var harnessV1ToolInputStartPartSchema = z2.object({
|
|
1068
|
+
type: z2.literal("tool-input-start"),
|
|
1069
|
+
id: z2.string(),
|
|
1070
|
+
toolName: z2.string(),
|
|
1071
|
+
providerMetadata: harnessV1ProviderMetadataSchema.optional(),
|
|
1072
|
+
providerExecuted: z2.boolean().optional(),
|
|
1073
|
+
dynamic: z2.boolean().optional(),
|
|
1074
|
+
title: z2.string().optional()
|
|
1075
|
+
});
|
|
1076
|
+
var harnessV1ToolInputDeltaPartSchema = z2.object({
|
|
1077
|
+
type: z2.literal("tool-input-delta"),
|
|
1078
|
+
id: z2.string(),
|
|
1079
|
+
delta: z2.string(),
|
|
1080
|
+
providerMetadata: harnessV1ProviderMetadataSchema.optional()
|
|
1081
|
+
});
|
|
1082
|
+
var harnessV1ToolInputEndPartSchema = z2.object({
|
|
1083
|
+
type: z2.literal("tool-input-end"),
|
|
1084
|
+
id: z2.string(),
|
|
1085
|
+
providerMetadata: harnessV1ProviderMetadataSchema.optional()
|
|
1086
|
+
});
|
|
787
1087
|
var harnessV1ToolCallPartSchema = z2.object({
|
|
788
1088
|
type: z2.literal("tool-call"),
|
|
789
1089
|
toolCallId: z2.string(),
|
|
@@ -853,6 +1153,9 @@ var harnessV1StreamPartSchema = z2.discriminatedUnion("type", [
|
|
|
853
1153
|
harnessV1ReasoningStartPartSchema,
|
|
854
1154
|
harnessV1ReasoningDeltaPartSchema,
|
|
855
1155
|
harnessV1ReasoningEndPartSchema,
|
|
1156
|
+
harnessV1ToolInputStartPartSchema,
|
|
1157
|
+
harnessV1ToolInputDeltaPartSchema,
|
|
1158
|
+
harnessV1ToolInputEndPartSchema,
|
|
856
1159
|
harnessV1ToolCallPartSchema,
|
|
857
1160
|
harnessV1ToolApprovalRequestPartSchema,
|
|
858
1161
|
harnessV1ToolResultPartSchema,
|
|
@@ -957,6 +1260,9 @@ var harnessV1BridgeOutboundMessageSchema = z3.discriminatedUnion(
|
|
|
957
1260
|
harnessV1ReasoningStartPartSchema,
|
|
958
1261
|
harnessV1ReasoningDeltaPartSchema,
|
|
959
1262
|
harnessV1ReasoningEndPartSchema,
|
|
1263
|
+
harnessV1ToolInputStartPartSchema,
|
|
1264
|
+
harnessV1ToolInputDeltaPartSchema,
|
|
1265
|
+
harnessV1ToolInputEndPartSchema,
|
|
960
1266
|
harnessV1ToolCallPartSchema,
|
|
961
1267
|
harnessV1ToolApprovalRequestPartSchema,
|
|
962
1268
|
harnessV1ToolResultPartSchema,
|
|
@@ -1127,7 +1433,7 @@ async function waitForBridgeReady({
|
|
|
1127
1433
|
if (value === void 0) continue;
|
|
1128
1434
|
for (const line of decoder.push(value)) {
|
|
1129
1435
|
pushTail({ lines: stdoutTail, line });
|
|
1130
|
-
const parsed = await
|
|
1436
|
+
const parsed = await safeParseJSON4({
|
|
1131
1437
|
text: line,
|
|
1132
1438
|
schema: harnessV1BridgeReadySchema
|
|
1133
1439
|
});
|
|
@@ -1164,7 +1470,7 @@ async function readBridgeMetaReady({
|
|
|
1164
1470
|
})
|
|
1165
1471
|
).catch(() => null);
|
|
1166
1472
|
if (raw == null) return void 0;
|
|
1167
|
-
const parsed = await
|
|
1473
|
+
const parsed = await safeParseJSON4({ text: raw, schema: bridgeMetaSchema });
|
|
1168
1474
|
if (!parsed.success) return void 0;
|
|
1169
1475
|
if (parsed.value.type !== bridgeType) return void 0;
|
|
1170
1476
|
if (parsed.value.state !== "waiting") return void 0;
|