@nodetool-ai/runtime 0.8.1 → 0.8.3
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/dist/.nodetool-build-stamp +1 -1
- package/dist/context.d.ts +31 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +369 -160
- package/dist/context.js.map +1 -1
- package/dist/generation-registry.d.ts +8 -0
- package/dist/generation-registry.d.ts.map +1 -1
- package/dist/generation-registry.js +18 -0
- package/dist/generation-registry.js.map +1 -1
- package/dist/host-binaries.d.ts.map +1 -1
- package/dist/host-binaries.js +18 -10
- package/dist/host-binaries.js.map +1 -1
- package/dist/image-codec.d.ts +2 -0
- package/dist/image-codec.d.ts.map +1 -1
- package/dist/image-codec.js +23 -3
- package/dist/image-codec.js.map +1 -1
- package/dist/image-model-tasks.d.ts +35 -0
- package/dist/image-model-tasks.d.ts.map +1 -0
- package/dist/image-model-tasks.js +67 -0
- package/dist/image-model-tasks.js.map +1 -0
- package/dist/index.d.ts +14 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/media-ref-bytes.d.ts +18 -2
- package/dist/media-ref-bytes.d.ts.map +1 -1
- package/dist/media-ref-bytes.js +26 -16
- package/dist/media-ref-bytes.js.map +1 -1
- package/dist/node-executor.d.ts +6 -0
- package/dist/node-executor.d.ts.map +1 -1
- package/dist/prompt-asset-refs.d.ts +12 -1
- package/dist/prompt-asset-refs.d.ts.map +1 -1
- package/dist/prompt-asset-refs.js +9 -4
- package/dist/prompt-asset-refs.js.map +1 -1
- package/dist/providers/aki-provider.d.ts +2 -0
- package/dist/providers/aki-provider.d.ts.map +1 -1
- package/dist/providers/aki-provider.js +6 -0
- package/dist/providers/aki-provider.js.map +1 -1
- package/dist/providers/api-route-provider.d.ts +22 -0
- package/dist/providers/api-route-provider.d.ts.map +1 -0
- package/dist/providers/api-route-provider.js +56 -0
- package/dist/providers/api-route-provider.js.map +1 -0
- package/dist/providers/atlascloud-provider.d.ts +2 -0
- package/dist/providers/atlascloud-provider.d.ts.map +1 -1
- package/dist/providers/atlascloud-provider.js +22 -0
- package/dist/providers/atlascloud-provider.js.map +1 -1
- package/dist/providers/base-provider.d.ts +36 -24
- package/dist/providers/base-provider.d.ts.map +1 -1
- package/dist/providers/base-provider.js +145 -150
- package/dist/providers/base-provider.js.map +1 -1
- package/dist/providers/chatgpt-provider.d.ts +48 -0
- package/dist/providers/chatgpt-provider.d.ts.map +1 -0
- package/dist/providers/chatgpt-provider.js +506 -0
- package/dist/providers/chatgpt-provider.js.map +1 -0
- package/dist/providers/claude-agent-provider.d.ts +6 -36
- package/dist/providers/claude-agent-provider.d.ts.map +1 -1
- package/dist/providers/claude-agent-provider.js +208 -26
- package/dist/providers/claude-agent-provider.js.map +1 -1
- package/dist/providers/codex-provider.d.ts +2 -0
- package/dist/providers/codex-provider.d.ts.map +1 -1
- package/dist/providers/codex-provider.js +15 -2
- package/dist/providers/codex-provider.js.map +1 -1
- package/dist/providers/cohere-provider.d.ts +2 -1
- package/dist/providers/cohere-provider.d.ts.map +1 -1
- package/dist/providers/cohere-provider.js +5 -0
- package/dist/providers/cohere-provider.js.map +1 -1
- package/dist/providers/context-window.d.ts.map +1 -1
- package/dist/providers/context-window.js +1 -0
- package/dist/providers/context-window.js.map +1 -1
- package/dist/providers/core-tools.d.ts +2 -1
- package/dist/providers/core-tools.d.ts.map +1 -1
- package/dist/providers/core-tools.js +2 -1
- package/dist/providers/core-tools.js.map +1 -1
- package/dist/providers/cost-calculator.d.ts.map +1 -1
- package/dist/providers/cost-calculator.js +9 -0
- package/dist/providers/cost-calculator.js.map +1 -1
- package/dist/providers/credential-check.d.ts +8 -0
- package/dist/providers/credential-check.d.ts.map +1 -1
- package/dist/providers/credential-check.js +27 -0
- package/dist/providers/credential-check.js.map +1 -1
- package/dist/providers/custom-openai-provider.d.ts +2 -0
- package/dist/providers/custom-openai-provider.d.ts.map +1 -1
- package/dist/providers/custom-openai-provider.js +27 -1
- package/dist/providers/custom-openai-provider.js.map +1 -1
- package/dist/providers/dreamina-models.d.ts +5 -0
- package/dist/providers/dreamina-models.d.ts.map +1 -0
- package/dist/providers/dreamina-models.js +57 -0
- package/dist/providers/dreamina-models.js.map +1 -0
- package/dist/providers/dreamina-music.d.ts +52 -0
- package/dist/providers/dreamina-music.d.ts.map +1 -0
- package/dist/providers/dreamina-music.js +115 -0
- package/dist/providers/dreamina-music.js.map +1 -0
- package/dist/providers/dreamina-provider.d.ts +64 -0
- package/dist/providers/dreamina-provider.d.ts.map +1 -0
- package/dist/providers/dreamina-provider.js +1001 -0
- package/dist/providers/dreamina-provider.js.map +1 -0
- package/dist/providers/elevenlabs-provider.d.ts +2 -1
- package/dist/providers/elevenlabs-provider.d.ts.map +1 -1
- package/dist/providers/elevenlabs-provider.js +5 -0
- package/dist/providers/elevenlabs-provider.js.map +1 -1
- package/dist/providers/evolink-provider.d.ts +2 -0
- package/dist/providers/evolink-provider.d.ts.map +1 -1
- package/dist/providers/evolink-provider.js +8 -0
- package/dist/providers/evolink-provider.js.map +1 -1
- package/dist/providers/extension-tab.d.ts +29 -0
- package/dist/providers/extension-tab.d.ts.map +1 -0
- package/dist/providers/extension-tab.js +144 -0
- package/dist/providers/extension-tab.js.map +1 -0
- package/dist/providers/fake-provider.d.ts +5 -2
- package/dist/providers/fake-provider.d.ts.map +1 -1
- package/dist/providers/fake-provider.js +73 -9
- package/dist/providers/fake-provider.js.map +1 -1
- package/dist/providers/fake-schema-answer.d.ts +10 -0
- package/dist/providers/fake-schema-answer.d.ts.map +1 -0
- package/dist/providers/fake-schema-answer.js +64 -0
- package/dist/providers/fake-schema-answer.js.map +1 -0
- package/dist/providers/fal-provider.d.ts +2 -1
- package/dist/providers/fal-provider.d.ts.map +1 -1
- package/dist/providers/fal-provider.js +32 -2
- package/dist/providers/fal-provider.js.map +1 -1
- package/dist/providers/gemini-provider.d.ts +2 -1
- package/dist/providers/gemini-provider.d.ts.map +1 -1
- package/dist/providers/gemini-provider.js +15 -0
- package/dist/providers/gemini-provider.js.map +1 -1
- package/dist/providers/gemini-web-provider.d.ts +76 -0
- package/dist/providers/gemini-web-provider.d.ts.map +1 -0
- package/dist/providers/gemini-web-provider.js +752 -0
- package/dist/providers/gemini-web-provider.js.map +1 -0
- package/dist/providers/higgsfield-provider.d.ts +2 -1
- package/dist/providers/higgsfield-provider.d.ts.map +1 -1
- package/dist/providers/higgsfield-provider.js +12 -0
- package/dist/providers/higgsfield-provider.js.map +1 -1
- package/dist/providers/huggingface-provider.d.ts +2 -1
- package/dist/providers/huggingface-provider.d.ts.map +1 -1
- package/dist/providers/huggingface-provider.js +27 -1
- package/dist/providers/huggingface-provider.js.map +1 -1
- package/dist/providers/index.d.ts +14 -3
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +48 -9
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/jina-provider.d.ts +2 -1
- package/dist/providers/jina-provider.d.ts.map +1 -1
- package/dist/providers/jina-provider.js +5 -0
- package/dist/providers/jina-provider.js.map +1 -1
- package/dist/providers/kie-provider.d.ts +2 -1
- package/dist/providers/kie-provider.d.ts.map +1 -1
- package/dist/providers/kie-provider.js +14 -0
- package/dist/providers/kie-provider.js.map +1 -1
- package/dist/providers/llama-provider.d.ts +12 -1
- package/dist/providers/llama-provider.d.ts.map +1 -1
- package/dist/providers/llama-provider.js +29 -5
- package/dist/providers/llama-provider.js.map +1 -1
- package/dist/providers/lmstudio-provider.js +2 -2
- package/dist/providers/lmstudio-provider.js.map +1 -1
- package/dist/providers/loop-tracing.d.ts +17 -0
- package/dist/providers/loop-tracing.d.ts.map +1 -0
- package/dist/providers/loop-tracing.js +132 -0
- package/dist/providers/loop-tracing.js.map +1 -0
- package/dist/providers/manifest-models.d.ts +2 -12
- package/dist/providers/manifest-models.d.ts.map +1 -1
- package/dist/providers/manifest-models.js +45 -3
- package/dist/providers/manifest-models.js.map +1 -1
- package/dist/providers/meshy-provider.d.ts +2 -1
- package/dist/providers/meshy-provider.d.ts.map +1 -1
- package/dist/providers/meshy-provider.js +6 -0
- package/dist/providers/meshy-provider.js.map +1 -1
- package/dist/providers/meta-provider.d.ts +53 -6
- package/dist/providers/meta-provider.d.ts.map +1 -1
- package/dist/providers/meta-provider.js +289 -6
- package/dist/providers/meta-provider.js.map +1 -1
- package/dist/providers/meta-segmentation.d.ts +27 -0
- package/dist/providers/meta-segmentation.d.ts.map +1 -0
- package/dist/providers/meta-segmentation.js +141 -0
- package/dist/providers/meta-segmentation.js.map +1 -0
- package/dist/providers/meta-transcription.d.ts +31 -0
- package/dist/providers/meta-transcription.d.ts.map +1 -0
- package/dist/providers/meta-transcription.js +187 -0
- package/dist/providers/meta-transcription.js.map +1 -0
- package/dist/providers/minimax-provider.d.ts +2 -0
- package/dist/providers/minimax-provider.d.ts.map +1 -1
- package/dist/providers/minimax-provider.js +11 -0
- package/dist/providers/minimax-provider.js.map +1 -1
- package/dist/providers/mistral-provider.d.ts +2 -0
- package/dist/providers/mistral-provider.d.ts.map +1 -1
- package/dist/providers/mistral-provider.js +5 -0
- package/dist/providers/mistral-provider.js.map +1 -1
- package/dist/providers/node-llama-cpp-provider.d.ts +8 -4
- package/dist/providers/node-llama-cpp-provider.d.ts.map +1 -1
- package/dist/providers/node-llama-cpp-provider.js +83 -61
- package/dist/providers/node-llama-cpp-provider.js.map +1 -1
- package/dist/providers/nodetool-provider.d.ts +1 -1
- package/dist/providers/nodetool-provider.d.ts.map +1 -1
- package/dist/providers/nodetool-provider.js +0 -2
- package/dist/providers/nodetool-provider.js.map +1 -1
- package/dist/providers/ollama-provider.d.ts +25 -1
- package/dist/providers/ollama-provider.d.ts.map +1 -1
- package/dist/providers/ollama-provider.js +145 -27
- package/dist/providers/ollama-provider.js.map +1 -1
- package/dist/providers/openai-compat/client.d.ts +10 -1
- package/dist/providers/openai-compat/client.d.ts.map +1 -1
- package/dist/providers/openai-compat/client.js +21 -3
- package/dist/providers/openai-compat/client.js.map +1 -1
- package/dist/providers/openai-compat/index.d.ts +1 -1
- package/dist/providers/openai-compat/index.d.ts.map +1 -1
- package/dist/providers/openai-compat/index.js +1 -1
- package/dist/providers/openai-compat/index.js.map +1 -1
- package/dist/providers/openai-compat/types.d.ts +4 -0
- package/dist/providers/openai-compat/types.d.ts.map +1 -1
- package/dist/providers/openai-compat-provider.d.ts +11 -0
- package/dist/providers/openai-compat-provider.d.ts.map +1 -1
- package/dist/providers/openai-compat-provider.js +47 -2
- package/dist/providers/openai-compat-provider.js.map +1 -1
- package/dist/providers/openai-provider.d.ts +23 -2
- package/dist/providers/openai-provider.d.ts.map +1 -1
- package/dist/providers/openai-provider.js +102 -21
- package/dist/providers/openai-provider.js.map +1 -1
- package/dist/providers/openrouter-provider.d.ts +52 -1
- package/dist/providers/openrouter-provider.d.ts.map +1 -1
- package/dist/providers/openrouter-provider.js +372 -11
- package/dist/providers/openrouter-provider.js.map +1 -1
- package/dist/providers/opper-provider.d.ts +31 -0
- package/dist/providers/opper-provider.d.ts.map +1 -0
- package/dist/providers/opper-provider.js +91 -0
- package/dist/providers/opper-provider.js.map +1 -0
- package/dist/providers/provider-error.d.ts.map +1 -1
- package/dist/providers/provider-error.js +7 -1
- package/dist/providers/provider-error.js.map +1 -1
- package/dist/providers/provider-generations.d.ts +2 -2
- package/dist/providers/provider-generations.js +2 -2
- package/dist/providers/provider-request-log.d.ts.map +1 -1
- package/dist/providers/provider-request-log.js +19 -7
- package/dist/providers/provider-request-log.js.map +1 -1
- package/dist/providers/python-provider.d.ts +6 -1
- package/dist/providers/python-provider.d.ts.map +1 -1
- package/dist/providers/python-provider.js +35 -14
- package/dist/providers/python-provider.js.map +1 -1
- package/dist/providers/replicate-provider.d.ts +2 -1
- package/dist/providers/replicate-provider.d.ts.map +1 -1
- package/dist/providers/replicate-provider.js +22 -0
- package/dist/providers/replicate-provider.js.map +1 -1
- package/dist/providers/requesty-provider.d.ts +30 -0
- package/dist/providers/requesty-provider.d.ts.map +1 -0
- package/dist/providers/requesty-provider.js +87 -0
- package/dist/providers/requesty-provider.js.map +1 -0
- package/dist/providers/responses-api.d.ts +12 -2
- package/dist/providers/responses-api.d.ts.map +1 -1
- package/dist/providers/responses-api.js +54 -3
- package/dist/providers/responses-api.js.map +1 -1
- package/dist/providers/reve-provider.d.ts +2 -1
- package/dist/providers/reve-provider.d.ts.map +1 -1
- package/dist/providers/reve-provider.js +6 -0
- package/dist/providers/reve-provider.js.map +1 -1
- package/dist/providers/rodin-provider.d.ts +2 -1
- package/dist/providers/rodin-provider.d.ts.map +1 -1
- package/dist/providers/rodin-provider.js +6 -0
- package/dist/providers/rodin-provider.js.map +1 -1
- package/dist/providers/scripted-provider.d.ts.map +1 -1
- package/dist/providers/scripted-provider.js +6 -1
- package/dist/providers/scripted-provider.js.map +1 -1
- package/dist/providers/together-operations.d.ts +27 -0
- package/dist/providers/together-operations.d.ts.map +1 -0
- package/dist/providers/together-operations.js +95 -0
- package/dist/providers/together-operations.js.map +1 -0
- package/dist/providers/together-provider.d.ts +5 -8
- package/dist/providers/together-provider.d.ts.map +1 -1
- package/dist/providers/together-provider.js +54 -159
- package/dist/providers/together-provider.js.map +1 -1
- package/dist/providers/topaz-provider.d.ts +2 -1
- package/dist/providers/topaz-provider.d.ts.map +1 -1
- package/dist/providers/topaz-provider.js +5 -0
- package/dist/providers/topaz-provider.js.map +1 -1
- package/dist/providers/types.d.ts +54 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/providers/useapi-provider.d.ts +2 -1
- package/dist/providers/useapi-provider.d.ts.map +1 -1
- package/dist/providers/useapi-provider.js +8 -0
- package/dist/providers/useapi-provider.js.map +1 -1
- package/dist/providers/vllm-provider.d.ts +9 -4
- package/dist/providers/vllm-provider.d.ts.map +1 -1
- package/dist/providers/vllm-provider.js +16 -8
- package/dist/providers/vllm-provider.js.map +1 -1
- package/dist/providers/voyage-provider.d.ts +2 -1
- package/dist/providers/voyage-provider.d.ts.map +1 -1
- package/dist/providers/voyage-provider.js +5 -0
- package/dist/providers/voyage-provider.js.map +1 -1
- package/dist/providers/xai-provider.d.ts +2 -0
- package/dist/providers/xai-provider.d.ts.map +1 -1
- package/dist/providers/xai-provider.js +8 -0
- package/dist/providers/xai-provider.js.map +1 -1
- package/dist/python-bridge-base.d.ts +16 -6
- package/dist/python-bridge-base.d.ts.map +1 -1
- package/dist/python-bridge-base.js +117 -40
- package/dist/python-bridge-base.js.map +1 -1
- package/dist/python-bridge-codec.d.ts +16 -1
- package/dist/python-bridge-codec.d.ts.map +1 -1
- package/dist/python-bridge-codec.js +60 -2
- package/dist/python-bridge-codec.js.map +1 -1
- package/dist/python-bridge-framing.d.ts +10 -1
- package/dist/python-bridge-framing.d.ts.map +1 -1
- package/dist/python-bridge-framing.js +33 -8
- package/dist/python-bridge-framing.js.map +1 -1
- package/dist/python-bridge-types.d.ts +26 -5
- package/dist/python-bridge-types.d.ts.map +1 -1
- package/dist/python-bridge-types.js.map +1 -1
- package/dist/python-node-executor.d.ts +14 -3
- package/dist/python-node-executor.d.ts.map +1 -1
- package/dist/python-node-executor.js +185 -3
- package/dist/python-node-executor.js.map +1 -1
- package/dist/python-stdio-bridge.d.ts +6 -0
- package/dist/python-stdio-bridge.d.ts.map +1 -1
- package/dist/python-stdio-bridge.js +25 -2
- package/dist/python-stdio-bridge.js.map +1 -1
- package/dist/recommended-models.d.ts.map +1 -1
- package/dist/recommended-models.js +20 -0
- package/dist/recommended-models.js.map +1 -1
- package/dist/run-context.d.ts +20 -0
- package/dist/run-context.d.ts.map +1 -0
- package/dist/run-context.js +18 -0
- package/dist/run-context.js.map +1 -0
- package/dist/run-trace-context.d.ts +5 -0
- package/dist/run-trace-context.d.ts.map +1 -0
- package/dist/run-trace-context.js +33 -0
- package/dist/run-trace-context.js.map +1 -0
- package/dist/run-trace-processor.d.ts +65 -0
- package/dist/run-trace-processor.d.ts.map +1 -0
- package/dist/run-trace-processor.js +418 -0
- package/dist/run-trace-processor.js.map +1 -0
- package/dist/run-trace-scope.d.ts +28 -0
- package/dist/run-trace-scope.d.ts.map +1 -0
- package/dist/run-trace-scope.js +51 -0
- package/dist/run-trace-scope.js.map +1 -0
- package/dist/run-trace-serialization.d.ts +5 -0
- package/dist/run-trace-serialization.d.ts.map +1 -0
- package/dist/run-trace-serialization.js +114 -0
- package/dist/run-trace-serialization.js.map +1 -0
- package/dist/span-record.d.ts +4 -0
- package/dist/span-record.d.ts.map +1 -0
- package/dist/span-record.js +48 -0
- package/dist/span-record.js.map +1 -0
- package/dist/storage-workspace.d.ts +3 -0
- package/dist/storage-workspace.d.ts.map +1 -1
- package/dist/storage-workspace.js +32 -17
- package/dist/storage-workspace.js.map +1 -1
- package/dist/swappable-python-bridge.d.ts +6 -6
- package/dist/swappable-python-bridge.d.ts.map +1 -1
- package/dist/swappable-python-bridge.js +10 -10
- package/dist/swappable-python-bridge.js.map +1 -1
- package/dist/telemetry.d.ts +9 -3
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +53 -20
- package/dist/telemetry.js.map +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +55 -3
- package/dist/testing.js.map +1 -1
- package/dist/trace-exporters.d.ts +2 -30
- package/dist/trace-exporters.d.ts.map +1 -1
- package/dist/trace-exporters.js +4 -42
- package/dist/trace-exporters.js.map +1 -1
- package/dist/traced-storage.d.ts +17 -0
- package/dist/traced-storage.d.ts.map +1 -0
- package/dist/traced-storage.js +41 -0
- package/dist/traced-storage.js.map +1 -0
- package/dist/tracing-helpers.d.ts +15 -22
- package/dist/tracing-helpers.d.ts.map +1 -1
- package/dist/tracing-helpers.js +38 -6
- package/dist/tracing-helpers.js.map +1 -1
- package/dist/trim-video-window.d.ts +8 -0
- package/dist/trim-video-window.d.ts.map +1 -0
- package/dist/trim-video-window.js +50 -0
- package/dist/trim-video-window.js.map +1 -0
- package/package.json +21 -5
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatGPT through the user's own logged-in chatgpt.com tab, driven by the
|
|
3
|
+
* NodeTool Chrome extension. No API key: requests run on the user's ChatGPT
|
|
4
|
+
* subscription.
|
|
5
|
+
*
|
|
6
|
+
* A turn is submitted through the page's own composer, so the site computes
|
|
7
|
+
* its anti-abuse tokens itself. The reply is read back from the conversation
|
|
8
|
+
* API (`/backend-api/conversation/<id>`), which needs only the session's
|
|
9
|
+
* bearer token.
|
|
10
|
+
*
|
|
11
|
+
* Every turn runs in a normal ChatGPT thread, so it shows in the user's
|
|
12
|
+
* history. A chat records the thread as its provider session and the next turn
|
|
13
|
+
* continues it, sending only the new messages. Temporary chats would keep the
|
|
14
|
+
* history clean, but ChatGPT can neither reopen them nor generate images in
|
|
15
|
+
* them.
|
|
16
|
+
*
|
|
17
|
+
* One tab serves every call, so calls run one at a time.
|
|
18
|
+
*/
|
|
19
|
+
import { createHash } from "node:crypto";
|
|
20
|
+
import { createLogger } from "@nodetool-ai/config";
|
|
21
|
+
import { PROVIDER_IDS } from "@nodetool-ai/protocol";
|
|
22
|
+
import { fetchExternalMedia } from "../external-media-fetch.js";
|
|
23
|
+
import { BaseProvider } from "./base-provider.js";
|
|
24
|
+
import { createExtensionTab, stageBytesInTab } from "./extension-tab.js";
|
|
25
|
+
import { detectImageMime } from "./image-mime.js";
|
|
26
|
+
const log = createLogger("nodetool.runtime.providers.chatgpt");
|
|
27
|
+
const HOST = "chatgpt.com";
|
|
28
|
+
const BASE_URL = `https://${HOST}`;
|
|
29
|
+
/** The model id that leaves the choice to ChatGPT. */
|
|
30
|
+
export const CHATGPT_AUTO_MODEL = "auto";
|
|
31
|
+
/** The one image model: ChatGPT's own image tool, run by the default chat model. */
|
|
32
|
+
export const CHATGPT_IMAGE_MODEL = "chatgpt-image";
|
|
33
|
+
const COMPOSER = 'form .ProseMirror[contenteditable="true"]';
|
|
34
|
+
const SUBMIT = 'form button[type="submit"]';
|
|
35
|
+
const POLL_INTERVAL_MS = 1_500;
|
|
36
|
+
const READY_TIMEOUT_MS = 20_000;
|
|
37
|
+
const CONVERSATION_ID_TIMEOUT_MS = 30_000;
|
|
38
|
+
const CHAT_TIMEOUT_MS = 10 * 60_000;
|
|
39
|
+
const IMAGE_TIMEOUT_MS = 10 * 60_000;
|
|
40
|
+
/** The send script waits in the page for uploads to finish before it clicks. */
|
|
41
|
+
const SEND_TIMEOUT_MS = 90_000;
|
|
42
|
+
const DOWNLOAD_TIMEOUT_MS = 120_000;
|
|
43
|
+
const MAX_POLL_FAILURES = 5;
|
|
44
|
+
const MODELS_TTL_MS = 10 * 60_000;
|
|
45
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
46
|
+
let tab = null;
|
|
47
|
+
/** Replace the tab. Tests use this to avoid a real browser. */
|
|
48
|
+
export function setChatGPTTab(next) {
|
|
49
|
+
tab = next;
|
|
50
|
+
liveModels = null;
|
|
51
|
+
}
|
|
52
|
+
function currentTab() {
|
|
53
|
+
return (tab ??= createExtensionTab(HOST));
|
|
54
|
+
}
|
|
55
|
+
/** Calls share one tab, so each waits for the previous one. */
|
|
56
|
+
let queue = Promise.resolve();
|
|
57
|
+
function serialized(run) {
|
|
58
|
+
const next = queue.then(run, run);
|
|
59
|
+
queue = next.catch(() => undefined);
|
|
60
|
+
return next;
|
|
61
|
+
}
|
|
62
|
+
/** Models read from the page during an earlier call, so listing never attaches. */
|
|
63
|
+
let liveModels = null;
|
|
64
|
+
/** The page fetches the session's bearer token first; every API script starts with this. */
|
|
65
|
+
const AUTH = `const __s = await (await fetch("/api/auth/session", { credentials: "include" })).json();
|
|
66
|
+
if (!__s || !__s.accessToken) throw new Error("NT_NOT_SIGNED_IN");
|
|
67
|
+
const __auth = { authorization: "Bearer " + __s.accessToken };`;
|
|
68
|
+
function signedOut(error) {
|
|
69
|
+
return error instanceof Error && error.message.includes("NT_NOT_SIGNED_IN");
|
|
70
|
+
}
|
|
71
|
+
function signInError() {
|
|
72
|
+
return new Error("ChatGPT is not signed in. Open https://chatgpt.com in Chrome, sign in, and try again");
|
|
73
|
+
}
|
|
74
|
+
function sleep(ms, signal) {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
if (signal?.aborted)
|
|
77
|
+
return reject(signal.reason ?? new Error("Aborted"));
|
|
78
|
+
const timer = setTimeout(() => { signal?.removeEventListener("abort", onAbort); resolve(); }, ms);
|
|
79
|
+
const onAbort = () => { clearTimeout(timer); reject(signal?.reason ?? new Error("Aborted")); };
|
|
80
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function evaluate(expression, timeoutMs) {
|
|
84
|
+
try {
|
|
85
|
+
return (await currentTab().evaluate(expression, timeoutMs));
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (signedOut(error))
|
|
89
|
+
throw signInError();
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function waitForComposer() {
|
|
94
|
+
const deadline = Date.now() + READY_TIMEOUT_MS;
|
|
95
|
+
while (Date.now() < deadline) {
|
|
96
|
+
if (await evaluate(`/*nt:ready*/ !!document.querySelector(${JSON.stringify(COMPOSER)})`))
|
|
97
|
+
return;
|
|
98
|
+
await sleep(250);
|
|
99
|
+
}
|
|
100
|
+
// A signed-out page has no composer, so tell that apart from a layout change.
|
|
101
|
+
await evaluate(`/*nt:session*/ (async () => { ${AUTH} return true; })()`);
|
|
102
|
+
throw new Error("The ChatGPT composer did not appear. The chatgpt.com page layout may have changed");
|
|
103
|
+
}
|
|
104
|
+
/** Read the conversation's current branch, root first, compacted in the page. */
|
|
105
|
+
async function readConversation(conversationId) {
|
|
106
|
+
return evaluate(`/*nt:conversation*/ (async () => {
|
|
107
|
+
${AUTH}
|
|
108
|
+
const response = await fetch("/backend-api/conversation/" + ${JSON.stringify(conversationId)}, { headers: __auth });
|
|
109
|
+
if (!response.ok) throw new Error("ChatGPT conversation request failed: HTTP " + response.status);
|
|
110
|
+
const data = await response.json();
|
|
111
|
+
const path = [];
|
|
112
|
+
let node = data.mapping && data.mapping[data.current_node];
|
|
113
|
+
while (node) {
|
|
114
|
+
const m = node.message;
|
|
115
|
+
if (m) {
|
|
116
|
+
const parts = (m.content && m.content.parts) || [];
|
|
117
|
+
path.unshift({
|
|
118
|
+
id: node.id,
|
|
119
|
+
role: m.author.role,
|
|
120
|
+
contentType: m.content.content_type,
|
|
121
|
+
status: m.status ?? null,
|
|
122
|
+
endTurn: m.end_turn ?? null,
|
|
123
|
+
text: parts.filter((p) => typeof p === "string").join(""),
|
|
124
|
+
images: parts.filter((p) => p && p.content_type === "image_asset_pointer").map((p) => p.asset_pointer)
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
node = data.mapping[node.parent];
|
|
128
|
+
}
|
|
129
|
+
return { currentNode: data.current_node ?? null, path };
|
|
130
|
+
})()`);
|
|
131
|
+
}
|
|
132
|
+
/** Put images into the composer's file input, the way a file picker would. */
|
|
133
|
+
async function attachImages(images) {
|
|
134
|
+
if (images.length === 0)
|
|
135
|
+
return;
|
|
136
|
+
const files = [];
|
|
137
|
+
for (const [index, image] of images.entries()) {
|
|
138
|
+
const type = detectImageMime(image);
|
|
139
|
+
const id = await stageBytesInTab(currentTab(), image);
|
|
140
|
+
files.push({ id, name: `image-${index + 1}.${type.split("/")[1] ?? "png"}`, type });
|
|
141
|
+
}
|
|
142
|
+
await evaluate(`/*nt:attach*/ (() => {
|
|
143
|
+
const files = ${JSON.stringify(files)};
|
|
144
|
+
const inputs = [...document.querySelectorAll('input[type="file"]')];
|
|
145
|
+
const input = inputs.find((i) => i.multiple && (i.accept === "" || i.accept.includes("image/"))) || inputs[0];
|
|
146
|
+
if (!input) throw new Error("The ChatGPT composer has no file input");
|
|
147
|
+
const transfer = new DataTransfer();
|
|
148
|
+
for (const f of files) {
|
|
149
|
+
const binary = atob(window.__ntStage[f.id]);
|
|
150
|
+
delete window.__ntStage[f.id];
|
|
151
|
+
transfer.items.add(new File([Uint8Array.from(binary, (c) => c.charCodeAt(0))], f.name, { type: f.type }));
|
|
152
|
+
}
|
|
153
|
+
input.files = transfer.files;
|
|
154
|
+
input.dispatchEvent(new Event("change", { bubbles: true }));
|
|
155
|
+
return true;
|
|
156
|
+
})()`);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Type the text and click send. An attachment's preview appears before its
|
|
160
|
+
* upload finishes, and a click during the upload is ignored while the button
|
|
161
|
+
* still looks enabled. So the script clicks, checks that the composer emptied,
|
|
162
|
+
* and clicks again until the page takes the message.
|
|
163
|
+
*/
|
|
164
|
+
async function submit(text, attachments) {
|
|
165
|
+
await evaluate(`/*nt:send*/ (async () => {
|
|
166
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
167
|
+
const composer = () => document.querySelector(${JSON.stringify(COMPOSER)});
|
|
168
|
+
composer().focus();
|
|
169
|
+
document.execCommand("insertText", false, ${JSON.stringify(text)});
|
|
170
|
+
const deadline = Date.now() + ${SEND_TIMEOUT_MS - 5_000};
|
|
171
|
+
while (Date.now() < deadline) {
|
|
172
|
+
const button = document.querySelector(${JSON.stringify(SUBMIT)});
|
|
173
|
+
const previews = document.querySelectorAll("form img").length >= ${attachments};
|
|
174
|
+
if (button && !button.disabled && previews) {
|
|
175
|
+
button.click();
|
|
176
|
+
for (let i = 0; i < 12; i++) {
|
|
177
|
+
await sleep(250);
|
|
178
|
+
const box = composer();
|
|
179
|
+
if (!box || box.innerText.trim() === "" || location.pathname.startsWith("/c/")) return true;
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
await sleep(250);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw new Error("ChatGPT did not accept the message: the send button stayed disabled or ignored the click");
|
|
186
|
+
})()`, SEND_TIMEOUT_MS);
|
|
187
|
+
}
|
|
188
|
+
async function waitForConversationId(signal) {
|
|
189
|
+
const deadline = Date.now() + CONVERSATION_ID_TIMEOUT_MS;
|
|
190
|
+
while (Date.now() < deadline) {
|
|
191
|
+
await sleep(500, signal);
|
|
192
|
+
// A new chat first shows a placeholder id (`local-…`); only a UUID is real.
|
|
193
|
+
const id = (await evaluate(`/*nt:location*/ location.pathname`)).match(/\/c\/([0-9a-f-]{36})/)?.[1];
|
|
194
|
+
if (id && UUID.test(id))
|
|
195
|
+
return id;
|
|
196
|
+
}
|
|
197
|
+
throw new Error("ChatGPT did not start a conversation after the message was sent");
|
|
198
|
+
}
|
|
199
|
+
/** The thread to continue is gone, so the caller starts a new one. Thrown before anything is sent. */
|
|
200
|
+
class ThreadUnavailableError extends Error {
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Poll until the turn ends: the current node is a new assistant message with
|
|
204
|
+
* `end_turn`. `before` is the current node before the send, whose finished
|
|
205
|
+
* reply must not count.
|
|
206
|
+
*/
|
|
207
|
+
async function waitForReply(conversationId, timeoutMs, signal, before = null) {
|
|
208
|
+
const started = Date.now();
|
|
209
|
+
let failures = 0;
|
|
210
|
+
let last = null;
|
|
211
|
+
for (;;) {
|
|
212
|
+
await sleep(POLL_INTERVAL_MS, signal);
|
|
213
|
+
try {
|
|
214
|
+
last = await readConversation(conversationId);
|
|
215
|
+
failures = 0;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
if (error instanceof Error && error.message.startsWith("ChatGPT is not signed in"))
|
|
219
|
+
throw error;
|
|
220
|
+
log.warn("ChatGPT poll failed", { conversationId, failures: failures + 1, error: error instanceof Error ? error.message : String(error) });
|
|
221
|
+
if (++failures > MAX_POLL_FAILURES)
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
const tail = last?.path.at(-1);
|
|
225
|
+
if (tail && tail.role === "assistant" && tail.endTurn === true && last.currentNode !== before)
|
|
226
|
+
return last;
|
|
227
|
+
if (Date.now() - started > timeoutMs) {
|
|
228
|
+
throw new Error(`ChatGPT did not finish within ${timeoutMs / 1000}s (last message: ${tail ? `${tail.role} ${tail.contentType} ${tail.status ?? ""}`.trim() : "none"}). The conversation is ${BASE_URL}/c/${conversationId}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/** Run one turn, in a new thread or a continued one, and return the reply. The caller holds the tab. */
|
|
233
|
+
async function runTurnHoldingTab(request) {
|
|
234
|
+
const query = new URLSearchParams();
|
|
235
|
+
if (request.model && request.model !== CHATGPT_AUTO_MODEL && request.model !== CHATGPT_IMAGE_MODEL)
|
|
236
|
+
query.set("model", request.model);
|
|
237
|
+
const search = query.toString() ? `?${query}` : "";
|
|
238
|
+
let before = null;
|
|
239
|
+
if (request.conversationId) {
|
|
240
|
+
await currentTab().navigate(`${BASE_URL}/c/${request.conversationId}${search}`);
|
|
241
|
+
await waitForComposer();
|
|
242
|
+
// A deleted or foreign thread redirects to a new chat.
|
|
243
|
+
const pathname = await evaluate(`/*nt:location*/ location.pathname`);
|
|
244
|
+
if (!pathname.includes(request.conversationId))
|
|
245
|
+
throw new ThreadUnavailableError(`ChatGPT thread ${request.conversationId} is no longer available`);
|
|
246
|
+
try {
|
|
247
|
+
before = (await readConversation(request.conversationId)).currentNode;
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
throw new ThreadUnavailableError(error instanceof Error ? error.message : String(error));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
await currentTab().navigate(`${BASE_URL}/${search}`);
|
|
255
|
+
await waitForComposer();
|
|
256
|
+
}
|
|
257
|
+
await attachImages(request.images);
|
|
258
|
+
await submit(request.text, request.images.length);
|
|
259
|
+
const conversationId = request.conversationId ?? (await waitForConversationId(request.signal));
|
|
260
|
+
log.info("ChatGPT turn submitted", { conversationId, model: request.model, continued: Boolean(request.conversationId), images: request.images.length });
|
|
261
|
+
const state = await waitForReply(conversationId, request.timeoutMs, request.signal, before);
|
|
262
|
+
await refreshModels();
|
|
263
|
+
return collectReply(conversationId, state);
|
|
264
|
+
}
|
|
265
|
+
/** The reply is everything after the last user message on the branch. */
|
|
266
|
+
function collectReply(conversationId, state) {
|
|
267
|
+
let lastUser = -1;
|
|
268
|
+
state.path.forEach((node, index) => { if (node.role === "user")
|
|
269
|
+
lastUser = index; });
|
|
270
|
+
const reply = state.path.slice(lastUser + 1);
|
|
271
|
+
const tail = reply.at(-1);
|
|
272
|
+
const text = tail && tail.contentType === "text" ? tail.text : "";
|
|
273
|
+
const images = [...new Set(reply.filter((node) => node.role === "tool").flatMap((node) => node.images))];
|
|
274
|
+
return { conversationId, text, images };
|
|
275
|
+
}
|
|
276
|
+
/** Resolve an image pointer (`sediment://file_…` or `file-service://file-…`) and fetch it in the tab. */
|
|
277
|
+
async function downloadImage(conversationId, pointer) {
|
|
278
|
+
const fileId = pointer.replace(/^[a-z-]+:\/\//, "");
|
|
279
|
+
const base64 = await evaluate(`/*nt:download*/ (async () => {
|
|
280
|
+
${AUTH}
|
|
281
|
+
const meta = await fetch("/backend-api/files/download/" + ${JSON.stringify(fileId)} + "?conversation_id=" + ${JSON.stringify(conversationId)} + "&inline=false", { headers: __auth });
|
|
282
|
+
if (!meta.ok) throw new Error("ChatGPT file lookup failed: HTTP " + meta.status);
|
|
283
|
+
const info = await meta.json();
|
|
284
|
+
if (!info.download_url) throw new Error("ChatGPT returned no download URL for the image");
|
|
285
|
+
const response = await fetch(info.download_url, { credentials: "include" });
|
|
286
|
+
if (!response.ok) throw new Error("ChatGPT image download failed: HTTP " + response.status);
|
|
287
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
288
|
+
let binary = "";
|
|
289
|
+
for (let i = 0; i < bytes.length; i += 0x8000) binary += String.fromCharCode.apply(null, bytes.subarray(i, i + 0x8000));
|
|
290
|
+
return btoa(binary);
|
|
291
|
+
})()`, DOWNLOAD_TIMEOUT_MS);
|
|
292
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
293
|
+
}
|
|
294
|
+
/** Read the account's model picker while the tab is attached anyway. */
|
|
295
|
+
async function refreshModels() {
|
|
296
|
+
if (liveModels && Date.now() - liveModels.at < MODELS_TTL_MS)
|
|
297
|
+
return;
|
|
298
|
+
try {
|
|
299
|
+
const listed = await evaluate(`/*nt:models*/ (async () => {
|
|
300
|
+
${AUTH}
|
|
301
|
+
const response = await fetch("/backend-api/models", { headers: __auth });
|
|
302
|
+
if (!response.ok) return [];
|
|
303
|
+
const data = await response.json();
|
|
304
|
+
return (data.models || []).map((m) => ({ slug: m.slug, title: m.title }));
|
|
305
|
+
})()`);
|
|
306
|
+
liveModels = {
|
|
307
|
+
at: Date.now(),
|
|
308
|
+
models: listed.filter((m) => typeof m.slug === "string" && m.slug).map((m) => ({ id: m.slug, name: `${m.title || m.slug} (${m.slug})`, provider: PROVIDER_IDS.CHATGPT }))
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
log.debug("ChatGPT model list unavailable", { error: error instanceof Error ? error.message : String(error) });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function textOf(content) {
|
|
316
|
+
if (typeof content === "string")
|
|
317
|
+
return content;
|
|
318
|
+
if (!Array.isArray(content))
|
|
319
|
+
return "";
|
|
320
|
+
return content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
321
|
+
}
|
|
322
|
+
function imagesOf(content) {
|
|
323
|
+
return Array.isArray(content) ? content.filter((part) => part.type === "image_url") : [];
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Flatten a conversation into one composer message. A single user message goes
|
|
327
|
+
* as it is. Otherwise the system prompt and the earlier turns become a
|
|
328
|
+
* transcript that ends with the last user message.
|
|
329
|
+
*/
|
|
330
|
+
export function composePrompt(messages) {
|
|
331
|
+
const system = messages.filter((m) => m.role === "system").map((m) => textOf(m.content)).filter(Boolean).join("\n\n");
|
|
332
|
+
const turns = messages.filter((m) => m.role !== "system");
|
|
333
|
+
if (!system && turns.length === 1 && turns[0].role === "user")
|
|
334
|
+
return textOf(turns[0].content);
|
|
335
|
+
const label = (m) => (m.role === "user" ? "User" : m.role === "assistant" ? "Assistant" : "Tool result");
|
|
336
|
+
const transcript = turns.map((m) => `${label(m)}: ${textOf(m.content)}`.trimEnd()).join("\n\n");
|
|
337
|
+
return [
|
|
338
|
+
system ? `Instructions:\n${system}` : "",
|
|
339
|
+
turns.length > 1 ? `Conversation so far:\n${transcript}\n\nReply to the last User message.` : textOf(turns[0]?.content ?? "")
|
|
340
|
+
].filter(Boolean).join("\n\n");
|
|
341
|
+
}
|
|
342
|
+
/** The new messages of a continued thread: ChatGPT already holds its own replies and the system prompt. */
|
|
343
|
+
export function composeDelta(delta) {
|
|
344
|
+
const turns = delta.filter((m) => m.role !== "assistant" && m.role !== "system");
|
|
345
|
+
if (turns.length === 1)
|
|
346
|
+
return textOf(turns[0].content);
|
|
347
|
+
return turns.map((m) => `${m.role === "tool" ? "Tool result" : "User"}: ${textOf(m.content)}`.trimEnd()).join("\n\n");
|
|
348
|
+
}
|
|
349
|
+
function hashSystemPrompt(messages) {
|
|
350
|
+
const system = messages.filter((m) => m.role === "system").map((m) => textOf(m.content)).join("\n\n");
|
|
351
|
+
return createHash("sha256").update(system).digest("hex").slice(0, 16);
|
|
352
|
+
}
|
|
353
|
+
function aspectHint(aspectRatio, width, height) {
|
|
354
|
+
if (aspectRatio)
|
|
355
|
+
return `Aspect ratio: ${aspectRatio}.`;
|
|
356
|
+
if (width && height)
|
|
357
|
+
return `Size: about ${width}x${height} pixels.`;
|
|
358
|
+
return "";
|
|
359
|
+
}
|
|
360
|
+
export class ChatGPTProvider extends BaseProvider {
|
|
361
|
+
static requiredSecrets() {
|
|
362
|
+
return [];
|
|
363
|
+
}
|
|
364
|
+
constructor(_secrets = {}) {
|
|
365
|
+
super(PROVIDER_IDS.CHATGPT);
|
|
366
|
+
}
|
|
367
|
+
declaredCapabilities() {
|
|
368
|
+
return ["text_to_image", "image_to_image"];
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Listing never attaches to the tab: it returns `auto` plus the account's
|
|
372
|
+
* models read during an earlier call. Any ChatGPT model slug also works as
|
|
373
|
+
* a model id.
|
|
374
|
+
*/
|
|
375
|
+
async getAvailableLanguageModels() {
|
|
376
|
+
const auto = { id: CHATGPT_AUTO_MODEL, name: "ChatGPT (default model)", provider: PROVIDER_IDS.CHATGPT };
|
|
377
|
+
return [auto, ...(liveModels?.models ?? [])];
|
|
378
|
+
}
|
|
379
|
+
async getAvailableImageModels() {
|
|
380
|
+
return [{
|
|
381
|
+
id: CHATGPT_IMAGE_MODEL,
|
|
382
|
+
name: "ChatGPT Images",
|
|
383
|
+
provider: PROVIDER_IDS.CHATGPT,
|
|
384
|
+
supportedTasks: ["text_to_image", "image_to_image"],
|
|
385
|
+
aspectRatios: ["1:1", "3:2", "2:3"]
|
|
386
|
+
}];
|
|
387
|
+
}
|
|
388
|
+
/** Threads by conversation thread id, for callers that do not persist the session themselves. */
|
|
389
|
+
sessions = new Map();
|
|
390
|
+
async generateMessage(args) {
|
|
391
|
+
const { result } = await this.chatTurn(args);
|
|
392
|
+
return { role: "assistant", content: result.text };
|
|
393
|
+
}
|
|
394
|
+
async *generateMessages(args) {
|
|
395
|
+
const { result, session } = await this.chatTurn(args);
|
|
396
|
+
if (args.threadId)
|
|
397
|
+
yield { type: "session", session };
|
|
398
|
+
yield { type: "chunk", content: result.text, content_type: "text", done: true };
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Continue the thread the prior session names, or start a new one. A thread
|
|
402
|
+
* continues when the model and system prompt still match and there are new
|
|
403
|
+
* messages; then only those are sent. A thread that is gone falls back to a
|
|
404
|
+
* new one with the whole conversation.
|
|
405
|
+
*/
|
|
406
|
+
async chatTurn(args) {
|
|
407
|
+
if (args.tools && args.tools.length > 0) {
|
|
408
|
+
log.warn("ChatGPT in the browser cannot call tools; sending the conversation without them", { tools: args.tools.length });
|
|
409
|
+
}
|
|
410
|
+
const systemHash = hashSystemPrompt(args.messages);
|
|
411
|
+
const threadId = args.threadId ?? null;
|
|
412
|
+
const prior = args.providerSession ?? (threadId ? this.sessions.get(threadId) ?? null : null);
|
|
413
|
+
const canResume = prior != null &&
|
|
414
|
+
prior.providerId === this.provider &&
|
|
415
|
+
prior.model === args.model &&
|
|
416
|
+
(prior.systemHash == null || prior.systemHash === systemHash) &&
|
|
417
|
+
args.messages.length > prior.checkpoint;
|
|
418
|
+
let result = null;
|
|
419
|
+
if (canResume && prior) {
|
|
420
|
+
const delta = args.messages.slice(prior.checkpoint);
|
|
421
|
+
const request = await this.turnRequest(args.model, composeDelta(delta), delta, args.signal);
|
|
422
|
+
try {
|
|
423
|
+
result = await serialized(() => runTurnHoldingTab({ ...request, conversationId: prior.token }));
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
if (!(error instanceof ThreadUnavailableError))
|
|
427
|
+
throw error;
|
|
428
|
+
log.warn("ChatGPT thread cannot continue; starting a new one", { conversationId: prior.token, error: error.message });
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (!result) {
|
|
432
|
+
// The caller may have sent only the delta; a new thread needs the whole conversation.
|
|
433
|
+
const messages = canResume && args.loadFullHistory ? await args.loadFullHistory() : args.messages;
|
|
434
|
+
const request = await this.turnRequest(args.model, composePrompt(messages), messages, args.signal);
|
|
435
|
+
result = await serialized(() => runTurnHoldingTab(request));
|
|
436
|
+
}
|
|
437
|
+
const session = {
|
|
438
|
+
providerId: this.provider,
|
|
439
|
+
model: args.model,
|
|
440
|
+
token: result.conversationId,
|
|
441
|
+
checkpoint: args.messages.length,
|
|
442
|
+
systemHash
|
|
443
|
+
};
|
|
444
|
+
// Cache only when the caller does not thread the session itself; its copy is authoritative.
|
|
445
|
+
if (threadId && args.providerSession == null)
|
|
446
|
+
this.sessions.set(threadId, session);
|
|
447
|
+
return { result, session };
|
|
448
|
+
}
|
|
449
|
+
/** A chat turn's request: the text plus the images of the last user message among `messages`. */
|
|
450
|
+
async turnRequest(model, text, messages, signal) {
|
|
451
|
+
const last = [...messages].reverse().find((m) => m.role === "user");
|
|
452
|
+
const images = last ? await Promise.all(imagesOf(last.content).map((part) => this.imageBytes(part, signal))) : [];
|
|
453
|
+
const dropped = messages.filter((m) => m !== last).reduce((n, m) => n + imagesOf(m.content).length, 0);
|
|
454
|
+
if (dropped > 0)
|
|
455
|
+
log.warn("ChatGPT gets images from the last user message only; dropping earlier ones", { dropped });
|
|
456
|
+
return { model, text, images, timeoutMs: CHAT_TIMEOUT_MS, signal };
|
|
457
|
+
}
|
|
458
|
+
async textToImage(params) {
|
|
459
|
+
return this.generateImage(params.prompt, [], params);
|
|
460
|
+
}
|
|
461
|
+
async imageToImage(images, params) {
|
|
462
|
+
if (images.length === 0)
|
|
463
|
+
throw new Error("imageToImage needs at least one source image");
|
|
464
|
+
return this.generateImage(params.prompt, images, { ...params, width: params.targetWidth, height: params.targetHeight });
|
|
465
|
+
}
|
|
466
|
+
async generateImage(prompt, images, params) {
|
|
467
|
+
const text = [
|
|
468
|
+
images.length > 0
|
|
469
|
+
? "Create one image with the image generation tool, based on the attached image(s). Do not ask questions."
|
|
470
|
+
: "Create one image with the image generation tool. Do not ask questions.",
|
|
471
|
+
prompt,
|
|
472
|
+
aspectHint(params.aspectRatio, params.width, params.height),
|
|
473
|
+
params.negativePrompt ? `Avoid: ${params.negativePrompt}.` : ""
|
|
474
|
+
].filter(Boolean).join("\n\n");
|
|
475
|
+
// The download runs in the same turn on the tab, so no other call can
|
|
476
|
+
// navigate the tab away in between.
|
|
477
|
+
return serialized(async () => {
|
|
478
|
+
const result = await runTurnHoldingTab({ model: CHATGPT_IMAGE_MODEL, text, images, timeoutMs: IMAGE_TIMEOUT_MS, signal: params.signal });
|
|
479
|
+
const pointer = result.images.at(-1);
|
|
480
|
+
if (!pointer) {
|
|
481
|
+
const said = result.text.trim();
|
|
482
|
+
throw new Error(`ChatGPT finished without an image${said ? `: ${said.slice(0, 300)}` : ""}. The conversation is ${BASE_URL}/c/${result.conversationId}`);
|
|
483
|
+
}
|
|
484
|
+
return downloadImage(result.conversationId, pointer);
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
/** Bytes of one image part: inline data, a data URI, an asset URI or a URL. */
|
|
488
|
+
async imageBytes(part, signal) {
|
|
489
|
+
const { data, uri } = part.image;
|
|
490
|
+
if (data instanceof Uint8Array && data.length > 0)
|
|
491
|
+
return data;
|
|
492
|
+
const fromDataUri = (value) => new Uint8Array(Buffer.from(value.slice(value.indexOf(",") + 1), "base64"));
|
|
493
|
+
if (typeof data === "string" && data.length > 0)
|
|
494
|
+
return data.startsWith("data:") ? fromDataUri(data) : new Uint8Array(Buffer.from(data, "base64"));
|
|
495
|
+
if (!uri)
|
|
496
|
+
throw new Error("Image part has neither data nor a URI");
|
|
497
|
+
const resolved = uri.startsWith("data:") ? uri : await this.resolveUri(uri);
|
|
498
|
+
if (resolved.startsWith("data:"))
|
|
499
|
+
return fromDataUri(resolved);
|
|
500
|
+
const response = await fetchExternalMedia(resolved, signal ? { signal } : undefined);
|
|
501
|
+
if (!response.ok)
|
|
502
|
+
throw new Error(`Image download failed: HTTP ${response.status}`);
|
|
503
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
//# sourceMappingURL=chatgpt-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatgpt-provider.js","sourceRoot":"","sources":["../../src/providers/chatgpt-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,46 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
* ClaudeAgentProvider — Claude reached through the official
|
|
3
|
-
* `@anthropic-ai/claude-agent-sdk` instead of an API key.
|
|
4
|
-
*
|
|
5
|
-
* Unlike {@link AnthropicProvider}, this provider sends no `ANTHROPIC_API_KEY`:
|
|
6
|
-
* the SDK drives the bundled `claude` binary (shipped as an optional platform
|
|
7
|
-
* dependency, so there is nothing to install on PATH) and lets it authenticate
|
|
8
|
-
* with the machine's logged-in Claude subscription (the credentials stored
|
|
9
|
-
* under `~/.claude`). The SDK streams `SDKMessage`s, which we translate into the
|
|
10
|
-
* cross-provider {@link ProviderStreamItem} stream.
|
|
11
|
-
*
|
|
12
|
-
* `@anthropic-ai/claude-agent-sdk` is a *soft* (optional peer) dependency: it is
|
|
13
|
-
* not installed by default and must be added with the package manager before
|
|
14
|
-
* this provider can run. It is loaded lazily via {@link loadSdk}, so a missing
|
|
15
|
-
* package surfaces as a clear install hint only when the provider is actually
|
|
16
|
-
* used — the rest of the runtime, and the browser worker bundle, never need it.
|
|
17
|
-
*
|
|
18
|
-
* It is a *pure LLM* provider: the agentic tool loop is collapsed to a single
|
|
19
|
-
* turn with every built-in tool disabled (`allowedTools: []`), filesystem
|
|
20
|
-
* settings/skills disabled (`settingSources: []`), permission prompts neutered
|
|
21
|
-
* (`permissionMode: "dontAsk"`), and the default agent system prompt fully
|
|
22
|
-
* replaced (`systemPrompt`), so the model behaves like a plain chat completion —
|
|
23
|
-
* text in, text (and thinking) out.
|
|
24
|
-
*
|
|
25
|
-
* Session continuity: when a `threadId` is supplied the provider routes the
|
|
26
|
-
* thread through a single upstream session and, on subsequent turns, resumes it
|
|
27
|
-
* (`options.resume`) and sends only the new user delta. The continuation token
|
|
28
|
-
* ({@link ProviderSession}) is surfaced as a {@link ProviderSessionUpdate} and
|
|
29
|
-
* persisted by the chat layer onto the assistant message; the in-memory map
|
|
30
|
-
* below is only a within-process cache (the DB column is authoritative).
|
|
31
|
-
*/
|
|
32
|
-
import type { McpSdkServerConfigWithInstance, Options, SdkMcpToolDefinition, SDKMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
1
|
+
import type { McpSdkServerConfigWithInstance, Options, SdkMcpToolDefinition, SDKMessage, SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
|
|
33
2
|
import { BaseProvider } from "./base-provider.js";
|
|
34
3
|
import { type LanguageModel, type Message, type MessageContent, type ProviderSession, type ProviderStreamItem, type ProviderSkill, type ProviderTool, type ToolCall } from "./types.js";
|
|
35
4
|
import type { RunBudget, TurnBudget } from "../turn-budget.js";
|
|
36
5
|
/**
|
|
37
6
|
* The subset of the SDK `query` signature this provider depends on. We only
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* richer `Query`) is assignable to this. Injectable for tests.
|
|
7
|
+
* pass a string for text-only turns or a structured user message for images,
|
|
8
|
+
* and consume the result as an async iterable. Injectable for tests.
|
|
41
9
|
*/
|
|
42
10
|
export type ClaudeQueryFn = (params: {
|
|
43
|
-
prompt: string
|
|
11
|
+
prompt: string | AsyncIterable<SDKUserMessage>;
|
|
44
12
|
options?: Options;
|
|
45
13
|
}) => AsyncIterable<SDKMessage>;
|
|
46
14
|
/** The SDK `createSdkMcpServer` factory. Injectable for tests. */
|
|
@@ -102,6 +70,7 @@ export declare class ClaudeAgentProvider extends BaseProvider {
|
|
|
102
70
|
executeTool?: (toolCall: ToolCall) => Promise<string | MessageContent[]>;
|
|
103
71
|
resolveMedia?: (messages: Message[]) => Promise<Message[]>;
|
|
104
72
|
maxIterations?: number;
|
|
73
|
+
providedToolsOnly?: boolean;
|
|
105
74
|
turnBudget?: TurnBudget | RunBudget;
|
|
106
75
|
workspaceDir?: string;
|
|
107
76
|
/**
|
|
@@ -113,6 +82,7 @@ export declare class ClaudeAgentProvider extends BaseProvider {
|
|
|
113
82
|
*/
|
|
114
83
|
skills?: ProviderSkill[];
|
|
115
84
|
}): AsyncGenerator<ProviderStreamItem>;
|
|
85
|
+
private generateSdkLoop;
|
|
116
86
|
generateMessages(args: {
|
|
117
87
|
messages: Message[];
|
|
118
88
|
model: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-agent-provider.d.ts","sourceRoot":"","sources":["../../src/providers/claude-agent-provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude-agent-provider.d.ts","sourceRoot":"","sources":["../../src/providers/claude-agent-provider.ts"],"names":[],"mappings":"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"}
|