@steipete/oracle 0.8.3 → 0.8.4
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/LICENSE +1 -1
- package/dist/src/browser/actions/attachments.js +44 -20
- package/package.json +4 -3
package/LICENSE
CHANGED
|
@@ -570,7 +570,7 @@ export async function uploadAttachmentFile(deps, attachment, logger, options) {
|
|
|
570
570
|
// keep it as a fallback, but strongly prefer visible (even sr-only 1x1) inputs.
|
|
571
571
|
const localSet = new Set(localInputs);
|
|
572
572
|
let idx = 0;
|
|
573
|
-
|
|
573
|
+
let candidates = inputs.map((el) => {
|
|
574
574
|
const accept = el.getAttribute('accept') || '';
|
|
575
575
|
const imageOnly = acceptIsImageOnly(accept);
|
|
576
576
|
const rect = el instanceof HTMLElement ? el.getBoundingClientRect() : { width: 0, height: 0 };
|
|
@@ -583,9 +583,18 @@ export async function uploadAttachmentFile(deps, attachment, logger, options) {
|
|
|
583
583
|
(!imageOnly ? 30 : isImageAttachment ? 20 : 5);
|
|
584
584
|
el.setAttribute('data-oracle-upload-candidate', 'true');
|
|
585
585
|
el.setAttribute('data-oracle-upload-idx', String(idx));
|
|
586
|
-
return { idx: idx++, score, imageOnly
|
|
586
|
+
return { idx: idx++, score, imageOnly };
|
|
587
587
|
});
|
|
588
588
|
|
|
589
|
+
// When the attachment isn't an image, avoid inputs that only accept images.
|
|
590
|
+
// Some ChatGPT surfaces expose multiple file inputs (e.g. image-only vs generic upload).
|
|
591
|
+
if (!isImageAttachment) {
|
|
592
|
+
const nonImage = candidates.filter((candidate) => !candidate.imageOnly);
|
|
593
|
+
if (nonImage.length > 0) {
|
|
594
|
+
candidates = nonImage;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
589
598
|
// Prefer higher scores first.
|
|
590
599
|
candidates.sort((a, b) => b.score - a.score);
|
|
591
600
|
return {
|
|
@@ -829,8 +838,8 @@ export async function uploadAttachmentFile(deps, attachment, logger, options) {
|
|
|
829
838
|
continue;
|
|
830
839
|
}
|
|
831
840
|
const baselineInputSnapshot = await readInputSnapshot(idx);
|
|
832
|
-
const gatherSignals = async () => {
|
|
833
|
-
const signalResult = await waitForAttachmentUiSignal(
|
|
841
|
+
const gatherSignals = async (waitMs = attachmentUiSignalWaitMs) => {
|
|
842
|
+
const signalResult = await waitForAttachmentUiSignal(waitMs);
|
|
834
843
|
const postInputSnapshot = await readInputSnapshot(idx);
|
|
835
844
|
const postInputSignals = inputSignalsFor(baselineInputSnapshot, postInputSnapshot);
|
|
836
845
|
const snapshot = await runtime
|
|
@@ -890,22 +899,6 @@ export async function uploadAttachmentFile(deps, attachment, logger, options) {
|
|
|
890
899
|
if (!hasExpectedFile) {
|
|
891
900
|
if (mode === 'set') {
|
|
892
901
|
await dom.setFileInputFiles({ nodeId: resultNode.nodeId, files: [attachment.path] });
|
|
893
|
-
await runtime
|
|
894
|
-
.evaluate({
|
|
895
|
-
expression: `(() => {
|
|
896
|
-
const input = document.querySelector('input[type="file"][data-oracle-upload-idx="${idx}"]');
|
|
897
|
-
if (!(input instanceof HTMLInputElement)) return false;
|
|
898
|
-
try {
|
|
899
|
-
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
900
|
-
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
901
|
-
return true;
|
|
902
|
-
} catch {
|
|
903
|
-
return false;
|
|
904
|
-
}
|
|
905
|
-
})()`,
|
|
906
|
-
returnByValue: true,
|
|
907
|
-
})
|
|
908
|
-
.catch(() => undefined);
|
|
909
902
|
}
|
|
910
903
|
else {
|
|
911
904
|
const selector = `input[type="file"][data-oracle-upload-idx="${idx}"]`;
|
|
@@ -930,12 +923,43 @@ export async function uploadAttachmentFile(deps, attachment, logger, options) {
|
|
|
930
923
|
const evaluation = await evaluateSignals(signalState.signalResult, signalState.postInputSignals, immediateInputMatch);
|
|
931
924
|
return { evaluation, signalState, immediateInputMatch };
|
|
932
925
|
};
|
|
926
|
+
const dispatchInputEvents = async () => {
|
|
927
|
+
await runtime
|
|
928
|
+
.evaluate({
|
|
929
|
+
expression: `(() => {
|
|
930
|
+
const input = document.querySelector('input[type="file"][data-oracle-upload-idx="${idx}"]');
|
|
931
|
+
if (!(input instanceof HTMLInputElement)) return false;
|
|
932
|
+
try {
|
|
933
|
+
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
934
|
+
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
935
|
+
return true;
|
|
936
|
+
} catch {
|
|
937
|
+
return false;
|
|
938
|
+
}
|
|
939
|
+
})()`,
|
|
940
|
+
returnByValue: true,
|
|
941
|
+
})
|
|
942
|
+
.catch(() => undefined);
|
|
943
|
+
};
|
|
933
944
|
let result = await runInputAttempt('set');
|
|
934
945
|
if (result.evaluation.status === 'ui') {
|
|
935
946
|
confirmedAttachment = true;
|
|
936
947
|
break;
|
|
937
948
|
}
|
|
938
949
|
if (result.evaluation.status === 'input') {
|
|
950
|
+
await dispatchInputEvents();
|
|
951
|
+
await delay(150);
|
|
952
|
+
const forcedState = await gatherSignals(1_500);
|
|
953
|
+
const forcedEvaluation = await evaluateSignals(forcedState.signalResult, forcedState.postInputSignals, result.immediateInputMatch);
|
|
954
|
+
if (forcedEvaluation.status === 'ui') {
|
|
955
|
+
confirmedAttachment = true;
|
|
956
|
+
break;
|
|
957
|
+
}
|
|
958
|
+
if (forcedEvaluation.status === 'input') {
|
|
959
|
+
logger('Attachment input set; proceeding without UI confirmation.');
|
|
960
|
+
inputConfirmed = true;
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
939
963
|
logger('Attachment input set; retrying with data transfer to trigger ChatGPT upload.');
|
|
940
964
|
await dom.setFileInputFiles({ nodeId: resultNode.nodeId, files: [] }).catch(() => undefined);
|
|
941
965
|
await delay(150);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steipete/oracle",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"description": "CLI wrapper around OpenAI Responses API with GPT-5.2 Pro (via gpt-5.1-pro alias), GPT-5.2, GPT-5.1, and GPT-5.1 Codex high reasoning modes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/bin/oracle-cli.js",
|
|
@@ -80,14 +80,15 @@
|
|
|
80
80
|
"markdansi": "0.2.0",
|
|
81
81
|
"openai": "^6.15.0",
|
|
82
82
|
"osc-progress": "^0.2.0",
|
|
83
|
+
"qs": "^6.14.1",
|
|
83
84
|
"shiki": "^3.20.0",
|
|
84
85
|
"toasted-notifier": "^10.1.0",
|
|
85
86
|
"tokentally": "^0.1.1",
|
|
86
|
-
"zod": "^4.
|
|
87
|
+
"zod": "^4.3.5"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
89
90
|
"@anthropic-ai/tokenizer": "^0.0.4",
|
|
90
|
-
"@biomejs/biome": "^2.3.
|
|
91
|
+
"@biomejs/biome": "^2.3.11",
|
|
91
92
|
"@cdktf/node-pty-prebuilt-multiarch": "0.10.2",
|
|
92
93
|
"@types/chrome-remote-interface": "^0.33.0",
|
|
93
94
|
"@types/inquirer": "^9.0.9",
|