@steipete/oracle 0.13.0 → 0.14.1
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/README.md +22 -11
- package/dist/bin/oracle-cli.js +71 -71
- package/dist/src/browser/actions/assistantResponse.js +93 -10
- package/dist/src/browser/actions/deepResearch.js +180 -52
- package/dist/src/browser/actions/modelSelection.js +357 -40
- package/dist/src/browser/actions/navigation.js +294 -65
- package/dist/src/browser/actions/promptComposer.js +50 -4
- package/dist/src/browser/actions/thinkingTime.js +517 -105
- package/dist/src/browser/artifacts.js +19 -0
- package/dist/src/browser/chatgptFiles.js +797 -0
- package/dist/src/browser/chatgptImages.js +256 -27
- package/dist/src/browser/chromeLifecycle.js +4 -0
- package/dist/src/browser/config.js +2 -0
- package/dist/src/browser/index.js +404 -41
- package/dist/src/browser/pageActions.js +1 -1
- package/dist/src/browser/policies.js +2 -6
- package/dist/src/browser/projectSourcesRunner.js +16 -3
- package/dist/src/browser/prompt.js +161 -36
- package/dist/src/browser/reattach.js +6 -2
- package/dist/src/browser/reattachability.js +22 -10
- package/dist/src/browser/recoverConversation.js +73 -0
- package/dist/src/browser/sessionRunner.js +4 -1
- package/dist/src/cli/browserConfig.js +6 -2
- package/dist/src/cli/browserDefaults.js +2 -1
- package/dist/src/cli/browserTabs.js +129 -54
- package/dist/src/cli/followup.js +72 -0
- package/dist/src/cli/help.js +1 -1
- package/dist/src/cli/options.js +24 -0
- package/dist/src/cli/reattachGuidance.js +8 -0
- package/dist/src/cli/runOptions.js +2 -12
- package/dist/src/cli/sessionCommand.js +4 -0
- package/dist/src/cli/sessionDisplay.js +17 -3
- package/dist/src/cli/sessionLineage.js +7 -4
- package/dist/src/cli/sessionRunner.js +16 -1
- package/dist/src/gemini-web/client.js +5 -10
- package/dist/src/gemini-web/executor.js +1 -24
- package/dist/src/gemini-web/models.js +83 -0
- package/dist/src/mcp/server.js +2 -0
- package/dist/src/mcp/tools/chatgptImage.js +132 -0
- package/dist/src/mcp/tools/consult.js +270 -175
- package/dist/src/mcp/types.js +13 -2
- package/dist/src/mcp/utils.js +87 -1
- package/dist/src/oracle/config.js +27 -1
- package/dist/src/oracle/files.js +4 -6
- package/dist/src/oracle/geminiModels.js +2 -0
- package/dist/src/oracle/markdown.js +36 -3
- package/dist/src/oracle/modelResolver.js +21 -13
- package/dist/src/oracle/promptAssembly.js +2 -4
- package/dist/src/oracle/request.js +3 -5
- package/dist/src/oracle/thinkingTime.js +40 -0
- package/dist/src/oracle/tokenStats.js +5 -1
- package/dist/src/oracle.js +1 -1
- package/dist/src/sessionManager.js +1 -0
- package/dist/vendor/oracle-notifier/build-notifier.sh +0 -0
- package/package.json +47 -58
- package/vendor/oracle-notifier/build-notifier.sh +0 -0
- package/dist/bin/oracle.js +0 -569
- package/dist/src/browser/chromeCookies.js +0 -312
- package/dist/src/browser/keytarShim.js +0 -56
- package/dist/src/browser/windowsCookies.js +0 -219
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/Info.plist +0 -20
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/Resources/OracleIcon.icns +0 -0
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/_CodeSignature/CodeResources +0 -128
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/Info.plist +0 -20
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/Resources/OracleIcon.icns +0 -0
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/_CodeSignature/CodeResources +0 -128
- package/vendor/oracle-notifier/README.md +0 -26
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
export const DEFAULT_GEMINI_WEB_MODEL = "gemini-3.1-pro";
|
|
3
|
+
export const FALLBACK_GEMINI_WEB_MODEL = "gemini-3.1-flash-lite";
|
|
4
|
+
const MODEL_SPECS = {
|
|
5
|
+
"gemini-3.1-flash-lite": {
|
|
6
|
+
hash: "1d44b34bcaa1c04d",
|
|
7
|
+
modelCode: 6,
|
|
8
|
+
thinkingCode: 1,
|
|
9
|
+
},
|
|
10
|
+
"gemini-3.5-flash": {
|
|
11
|
+
hash: "56fdd199312815e2",
|
|
12
|
+
modelCode: 1,
|
|
13
|
+
thinkingCode: 1,
|
|
14
|
+
},
|
|
15
|
+
"gemini-3.1-pro": {
|
|
16
|
+
hash: "797f3d0293f288ad",
|
|
17
|
+
modelCode: 3,
|
|
18
|
+
thinkingCode: 1,
|
|
19
|
+
},
|
|
20
|
+
"gemini-3-pro-deep-think": {
|
|
21
|
+
hash: "797f3d0293f288ad",
|
|
22
|
+
modelCode: 3,
|
|
23
|
+
thinkingCode: 3,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
let clientId;
|
|
27
|
+
function getGeminiWebClientId() {
|
|
28
|
+
clientId ??= randomUUID().toUpperCase();
|
|
29
|
+
return clientId;
|
|
30
|
+
}
|
|
31
|
+
export function buildGeminiWebModelHeader(model, webClientId = getGeminiWebClientId()) {
|
|
32
|
+
const spec = MODEL_SPECS[model];
|
|
33
|
+
return JSON.stringify([
|
|
34
|
+
1,
|
|
35
|
+
null,
|
|
36
|
+
null,
|
|
37
|
+
null,
|
|
38
|
+
spec.hash,
|
|
39
|
+
null,
|
|
40
|
+
null,
|
|
41
|
+
1,
|
|
42
|
+
[4, 5, 6, 8],
|
|
43
|
+
null,
|
|
44
|
+
null,
|
|
45
|
+
3,
|
|
46
|
+
null,
|
|
47
|
+
null,
|
|
48
|
+
spec.modelCode,
|
|
49
|
+
spec.thinkingCode,
|
|
50
|
+
webClientId,
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
export function resolveGeminiWebModel(desiredModel, log) {
|
|
54
|
+
const desired = typeof desiredModel === "string" ? desiredModel.trim() : "";
|
|
55
|
+
if (!desired)
|
|
56
|
+
return DEFAULT_GEMINI_WEB_MODEL;
|
|
57
|
+
const normalized = desired.toLowerCase().replace(/[_\s]+/g, "-");
|
|
58
|
+
switch (normalized) {
|
|
59
|
+
case "gemini-3.1-pro":
|
|
60
|
+
case "gemini-3-pro":
|
|
61
|
+
case "gemini-3.0-pro":
|
|
62
|
+
return "gemini-3.1-pro";
|
|
63
|
+
case "gemini-3.5-flash":
|
|
64
|
+
return "gemini-3.5-flash";
|
|
65
|
+
case "gemini-3.1-flash-lite":
|
|
66
|
+
case "gemini-3.1-flashlite":
|
|
67
|
+
return "gemini-3.1-flash-lite";
|
|
68
|
+
case "gemini-3-deep-think":
|
|
69
|
+
case "gemini-3-pro-deep-think":
|
|
70
|
+
case "gemini-3-pro-deepthink":
|
|
71
|
+
case "gemini-3.1-pro-deep-think":
|
|
72
|
+
return "gemini-3-pro-deep-think";
|
|
73
|
+
case "gemini-2.5-pro":
|
|
74
|
+
return "gemini-3.1-pro";
|
|
75
|
+
case "gemini-2.5-flash":
|
|
76
|
+
return "gemini-3.1-flash-lite";
|
|
77
|
+
default:
|
|
78
|
+
if (normalized.startsWith("gemini-") || normalized.includes("gemini")) {
|
|
79
|
+
log?.(`[gemini-web] Unsupported Gemini web model "${desired}". Falling back to ${DEFAULT_GEMINI_WEB_MODEL}.`);
|
|
80
|
+
}
|
|
81
|
+
return DEFAULT_GEMINI_WEB_MODEL;
|
|
82
|
+
}
|
|
83
|
+
}
|
package/dist/src/mcp/server.js
CHANGED
|
@@ -5,6 +5,7 @@ import { pathToFileURL } from "node:url";
|
|
|
5
5
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
7
|
import { getCliVersion } from "../version.js";
|
|
8
|
+
import { registerChatGptImageTool } from "./tools/chatgptImage.js";
|
|
8
9
|
import { registerConsultTool } from "./tools/consult.js";
|
|
9
10
|
import { registerProjectSourcesTool } from "./tools/projectSources.js";
|
|
10
11
|
import { registerSessionsTool } from "./tools/sessions.js";
|
|
@@ -19,6 +20,7 @@ export async function startMcpServer() {
|
|
|
19
20
|
},
|
|
20
21
|
});
|
|
21
22
|
registerConsultTool(server);
|
|
23
|
+
registerChatGptImageTool(server);
|
|
22
24
|
registerProjectSourcesTool(server);
|
|
23
25
|
registerSessionsTool(server);
|
|
24
26
|
registerSessionResources(server);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { getOracleHomeDir } from "../../oracleHome.js";
|
|
5
|
+
import { browserThinkingTimeInputSchema, browserThinkingTimeRawSchema, } from "../types.js";
|
|
6
|
+
import { consultOutputShape, runConsultTool } from "./consult.js";
|
|
7
|
+
const chatGptImageInputShape = {
|
|
8
|
+
prompt: z.string().min(1, "Prompt is required.").describe("Image generation prompt."),
|
|
9
|
+
files: z
|
|
10
|
+
.array(z.string())
|
|
11
|
+
.default([])
|
|
12
|
+
.describe("Optional reference image/file paths or globs to upload to ChatGPT."),
|
|
13
|
+
outputPath: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Where to save the first generated image. Defaults to a unique file under ORACLE_HOME_DIR/generated/."),
|
|
17
|
+
aspectRatio: z
|
|
18
|
+
.string()
|
|
19
|
+
.optional()
|
|
20
|
+
.describe('Optional requested image aspect ratio, e.g. "1:1", "9:16", or "16:9".'),
|
|
21
|
+
model: z
|
|
22
|
+
.string()
|
|
23
|
+
.refine((value) => !/^(claude|gemini|grok)(?:[-\s]|$)/i.test(value.trim()), {
|
|
24
|
+
message: "chatgpt_image requires a ChatGPT/GPT model.",
|
|
25
|
+
})
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Optional ChatGPT/browser model label or alias. Defaults follow Oracle config."),
|
|
28
|
+
browserModelLabel: z.string().optional().describe("Explicit ChatGPT UI model label to select."),
|
|
29
|
+
browserAttachments: z
|
|
30
|
+
.enum(["auto", "never", "always"])
|
|
31
|
+
.optional()
|
|
32
|
+
.describe('How to deliver files. Defaults to "always" when files are present so reference images are uploaded.'),
|
|
33
|
+
browserThinkingTime: browserThinkingTimeRawSchema
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Set ChatGPT thinking time when supported by the chosen model."),
|
|
36
|
+
browserModelStrategy: z
|
|
37
|
+
.enum(["select", "current", "ignore"])
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Model picker strategy. Mirrors the consult tool and CLI browser flag."),
|
|
40
|
+
browserArchive: z
|
|
41
|
+
.enum(["auto", "always", "never"])
|
|
42
|
+
.optional()
|
|
43
|
+
.describe("Archive completed ChatGPT conversations after local artifacts are saved."),
|
|
44
|
+
browserKeepBrowser: z
|
|
45
|
+
.boolean()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe("Keep Chrome running after completion for debugging."),
|
|
48
|
+
dryRun: z
|
|
49
|
+
.boolean()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe("Preview the resolved image run without touching the browser."),
|
|
52
|
+
slug: z.string().optional().describe("Optional human-friendly session id."),
|
|
53
|
+
};
|
|
54
|
+
const chatGptImageOutputShape = {
|
|
55
|
+
// Mirror the consult output contract so structuredContent stays consistent
|
|
56
|
+
// (images/artifacts/resolved are typed by the shared consult shapes), plus the
|
|
57
|
+
// image-specific echo of the requested path.
|
|
58
|
+
...consultOutputShape,
|
|
59
|
+
requestedOutputPath: z.string(),
|
|
60
|
+
};
|
|
61
|
+
const chatGptImageInputSchema = z
|
|
62
|
+
.object({
|
|
63
|
+
...chatGptImageInputShape,
|
|
64
|
+
browserThinkingTime: browserThinkingTimeInputSchema.optional(),
|
|
65
|
+
})
|
|
66
|
+
.strict();
|
|
67
|
+
function resolveDefaultImageOutputPath() {
|
|
68
|
+
// Include a random token so concurrent agent calls in the same millisecond do
|
|
69
|
+
// not resolve to the same default path and overwrite each other.
|
|
70
|
+
const unique = `${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
|
|
71
|
+
return path.join(getOracleHomeDir(), "generated", `chatgpt-image-${unique}.png`);
|
|
72
|
+
}
|
|
73
|
+
function appendAspectRatio(prompt, aspectRatio) {
|
|
74
|
+
const requestedAspectRatio = aspectRatio?.trim();
|
|
75
|
+
if (!requestedAspectRatio) {
|
|
76
|
+
return prompt.trim();
|
|
77
|
+
}
|
|
78
|
+
return `${prompt.trim()}\n\nCreate the image with aspect ratio ${requestedAspectRatio}.`;
|
|
79
|
+
}
|
|
80
|
+
export function buildChatGptImageConsultInput(input) {
|
|
81
|
+
const files = input.files ?? [];
|
|
82
|
+
const outputPath = input.outputPath?.trim() || resolveDefaultImageOutputPath();
|
|
83
|
+
const browserAttachments = input.browserAttachments ?? (files.length > 0 ? "always" : undefined);
|
|
84
|
+
return {
|
|
85
|
+
prompt: appendAspectRatio(input.prompt, input.aspectRatio),
|
|
86
|
+
files,
|
|
87
|
+
model: input.model,
|
|
88
|
+
engine: "browser",
|
|
89
|
+
browserModelLabel: input.browserModelLabel,
|
|
90
|
+
browserAttachments,
|
|
91
|
+
browserThinkingTime: input.browserThinkingTime,
|
|
92
|
+
browserModelStrategy: input.browserModelStrategy,
|
|
93
|
+
browserArchive: input.browserArchive,
|
|
94
|
+
browserKeepBrowser: input.browserKeepBrowser,
|
|
95
|
+
generateImage: outputPath,
|
|
96
|
+
dryRun: input.dryRun,
|
|
97
|
+
slug: input.slug,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function registerChatGptImageTool(server) {
|
|
101
|
+
server.registerTool("chatgpt_image", {
|
|
102
|
+
title: "Generate an image with ChatGPT",
|
|
103
|
+
description: "Agent-friendly wrapper for ChatGPT browser image generation. It selects browser mode, enables the image-aware wait/download path, uploads reference files when provided, and returns saved image paths in structuredContent.images.",
|
|
104
|
+
inputSchema: chatGptImageInputShape,
|
|
105
|
+
outputSchema: chatGptImageOutputShape,
|
|
106
|
+
}, async (input) => {
|
|
107
|
+
const textContent = (text) => [{ type: "text", text }];
|
|
108
|
+
let parsed;
|
|
109
|
+
try {
|
|
110
|
+
parsed = chatGptImageInputSchema.parse(input);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
return {
|
|
114
|
+
isError: true,
|
|
115
|
+
content: textContent(error instanceof Error ? error.message : String(error)),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const consultInput = buildChatGptImageConsultInput(parsed);
|
|
119
|
+
const result = await runConsultTool(consultInput, { server: server.server });
|
|
120
|
+
if (result.isError || !result.structuredContent) {
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
const structuredContent = {
|
|
124
|
+
...result.structuredContent,
|
|
125
|
+
requestedOutputPath: consultInput.generateImage,
|
|
126
|
+
};
|
|
127
|
+
return {
|
|
128
|
+
...result,
|
|
129
|
+
structuredContent,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|