@bbclaw/core 0.1.0
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/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic/index.d.ts +44 -0
- package/dist/providers/anthropic/index.d.ts.map +1 -0
- package/dist/providers/anthropic/index.js +75 -0
- package/dist/providers/anthropic/index.js.map +1 -0
- package/dist/providers/index.d.ts +8 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-compat/index.d.ts +59 -0
- package/dist/providers/openai-compat/index.d.ts.map +1 -0
- package/dist/providers/openai-compat/index.js +175 -0
- package/dist/providers/openai-compat/index.js.map +1 -0
- package/dist/providers/openai-compat/presets.d.ts +22 -0
- package/dist/providers/openai-compat/presets.d.ts.map +1 -0
- package/dist/providers/openai-compat/presets.js +73 -0
- package/dist/providers/openai-compat/presets.js.map +1 -0
- package/dist/providers/openai-compat/requestTranslate.d.ts +39 -0
- package/dist/providers/openai-compat/requestTranslate.d.ts.map +1 -0
- package/dist/providers/openai-compat/requestTranslate.js +228 -0
- package/dist/providers/openai-compat/requestTranslate.js.map +1 -0
- package/dist/providers/openai-compat/sseParser.d.ts +29 -0
- package/dist/providers/openai-compat/sseParser.d.ts.map +1 -0
- package/dist/providers/openai-compat/sseParser.js +139 -0
- package/dist/providers/openai-compat/sseParser.js.map +1 -0
- package/dist/providers/openai-compat/streamAdapter.d.ts +45 -0
- package/dist/providers/openai-compat/streamAdapter.d.ts.map +1 -0
- package/dist/providers/openai-compat/streamAdapter.js +233 -0
- package/dist/providers/openai-compat/streamAdapter.js.map +1 -0
- package/dist/providers/openai-compat/types.d.ts +126 -0
- package/dist/providers/openai-compat/types.d.ts.map +1 -0
- package/dist/providers/openai-compat/types.js +11 -0
- package/dist/providers/openai-compat/types.js.map +1 -0
- package/dist/providers/selector.d.ts +52 -0
- package/dist/providers/selector.d.ts.map +1 -0
- package/dist/providers/selector.js +101 -0
- package/dist/providers/selector.js.map +1 -0
- package/dist/providers/types.d.ts +114 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +152 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/web-bridge/deepseek/spec.d.ts +22 -0
- package/dist/providers/web-bridge/deepseek/spec.d.ts.map +1 -0
- package/dist/providers/web-bridge/deepseek/spec.js +70 -0
- package/dist/providers/web-bridge/deepseek/spec.js.map +1 -0
- package/dist/providers/web-bridge/historySerializer.d.ts +49 -0
- package/dist/providers/web-bridge/historySerializer.d.ts.map +1 -0
- package/dist/providers/web-bridge/historySerializer.js +152 -0
- package/dist/providers/web-bridge/historySerializer.js.map +1 -0
- package/dist/providers/web-bridge/index.d.ts +10 -0
- package/dist/providers/web-bridge/index.d.ts.map +1 -0
- package/dist/providers/web-bridge/index.js +10 -0
- package/dist/providers/web-bridge/index.js.map +1 -0
- package/dist/providers/web-bridge/promptInjector.d.ts +63 -0
- package/dist/providers/web-bridge/promptInjector.d.ts.map +1 -0
- package/dist/providers/web-bridge/promptInjector.js +189 -0
- package/dist/providers/web-bridge/promptInjector.js.map +1 -0
- package/dist/providers/web-bridge/provider.d.ts +59 -0
- package/dist/providers/web-bridge/provider.d.ts.map +1 -0
- package/dist/providers/web-bridge/provider.js +176 -0
- package/dist/providers/web-bridge/provider.js.map +1 -0
- package/dist/providers/web-bridge/shared/BrowserSession.d.ts +51 -0
- package/dist/providers/web-bridge/shared/BrowserSession.d.ts.map +1 -0
- package/dist/providers/web-bridge/shared/BrowserSession.js +88 -0
- package/dist/providers/web-bridge/shared/BrowserSession.js.map +1 -0
- package/dist/providers/web-bridge/shared/WebBridgeAdapter.d.ts +97 -0
- package/dist/providers/web-bridge/shared/WebBridgeAdapter.d.ts.map +1 -0
- package/dist/providers/web-bridge/shared/WebBridgeAdapter.js +359 -0
- package/dist/providers/web-bridge/shared/WebBridgeAdapter.js.map +1 -0
- package/dist/providers/web-bridge/shared/observerScript.d.ts +41 -0
- package/dist/providers/web-bridge/shared/observerScript.d.ts.map +1 -0
- package/dist/providers/web-bridge/shared/observerScript.js +138 -0
- package/dist/providers/web-bridge/shared/observerScript.js.map +1 -0
- package/dist/providers/web-bridge/shared/types.d.ts +94 -0
- package/dist/providers/web-bridge/shared/types.d.ts.map +1 -0
- package/dist/providers/web-bridge/shared/types.js +25 -0
- package/dist/providers/web-bridge/shared/types.js.map +1 -0
- package/dist/providers/web-bridge/toolUseParser.d.ts +70 -0
- package/dist/providers/web-bridge/toolUseParser.d.ts.map +1 -0
- package/dist/providers/web-bridge/toolUseParser.js +360 -0
- package/dist/providers/web-bridge/toolUseParser.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider abstraction.
|
|
3
|
+
*
|
|
4
|
+
* BBClaw's agent runtime speaks one internal protocol: the type vocabulary of
|
|
5
|
+
* the official Anthropic SDK (Message, MessageParam, RawMessageStreamEvent,
|
|
6
|
+
* etc). We use those types because they're a published npm package and they
|
|
7
|
+
* happen to be the most expressive of the major LLM schemas (content blocks,
|
|
8
|
+
* tool_use, thinking, cache_control all model the world we care about).
|
|
9
|
+
*
|
|
10
|
+
* Non-Anthropic providers translate to/from these types at their own
|
|
11
|
+
* boundaries — see openai-compat/requestTranslate.ts and streamAdapter.ts.
|
|
12
|
+
*/
|
|
13
|
+
import type { ContentBlockParam, Message, MessageCreateParamsStreaming, MessageParam, MessageStreamParams, RawMessageStreamEvent, TextBlockParam, Tool, ToolResultBlockParam, ToolUseBlockParam, ToolUnion } from '@anthropic-ai/sdk/resources/messages/messages.js';
|
|
14
|
+
import type { Logger, ProviderKind } from '@bbclaw/shared';
|
|
15
|
+
/**
|
|
16
|
+
* Re-export the Anthropic SDK message vocabulary as the canonical internal
|
|
17
|
+
* protocol. Downstream packages (cli, apps) consume these from @bbclaw/core
|
|
18
|
+
* rather than depending on the SDK directly.
|
|
19
|
+
*/
|
|
20
|
+
export type { ContentBlockParam, Message, MessageCreateParamsStreaming, MessageParam, MessageStreamParams, RawMessageStreamEvent, TextBlockParam, Tool, ToolResultBlockParam, ToolUseBlockParam, ToolUnion, };
|
|
21
|
+
/**
|
|
22
|
+
* What a provider claims it can do. Every field defaults to the least-powerful
|
|
23
|
+
* answer (see FAIL_CLOSED_CAPABILITIES below). A provider that forgets a flag
|
|
24
|
+
* gracefully degrades, never accidentally unlocks something it can't deliver.
|
|
25
|
+
*/
|
|
26
|
+
export interface ProviderCapabilities {
|
|
27
|
+
/** Native function-calling on the wire. False → caller must use prompt-injected emulation. */
|
|
28
|
+
nativeTools: boolean;
|
|
29
|
+
/** Honors cache_control breakpoints. False → caller should strip them before sending. */
|
|
30
|
+
promptCaching: boolean;
|
|
31
|
+
/** Returns thinking/reasoning blocks as structured content. */
|
|
32
|
+
extendedThinking: boolean;
|
|
33
|
+
/** Accepts image inputs. */
|
|
34
|
+
vision: boolean;
|
|
35
|
+
/** Conservative estimate of how much we can fit in one request. */
|
|
36
|
+
contextWindow: number;
|
|
37
|
+
/** Cap on output tokens. */
|
|
38
|
+
maxOutputTokens: number;
|
|
39
|
+
/** Streaming supported. (We require this, but flag it explicitly so synthetic providers can declare it.) */
|
|
40
|
+
streaming: boolean;
|
|
41
|
+
}
|
|
42
|
+
export declare const FAIL_CLOSED_CAPABILITIES: ProviderCapabilities;
|
|
43
|
+
export interface HealthCheckResult {
|
|
44
|
+
ok: boolean;
|
|
45
|
+
/** Round-trip time for a probe request, when measurable. */
|
|
46
|
+
latencyMs?: number;
|
|
47
|
+
/** Free-form reason on failure. Surface to user. */
|
|
48
|
+
reason?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Every backend BBClaw can talk to implements this.
|
|
52
|
+
*
|
|
53
|
+
* The contract is intentionally minimal: stream a turn, do a one-shot, probe
|
|
54
|
+
* health, clean up. Anything else (cost tracking, retries, fallback) lives
|
|
55
|
+
* one layer up so it can be applied uniformly across providers.
|
|
56
|
+
*/
|
|
57
|
+
export interface Provider {
|
|
58
|
+
/** Family — used for capability-based dispatch (e.g. "is this an API provider?"). */
|
|
59
|
+
readonly kind: ProviderKind;
|
|
60
|
+
/** Stable instance id, e.g. 'anthropic-default', 'openai-personal', 'deepseek-web'. */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Human-readable label for UI. */
|
|
63
|
+
readonly displayName: string;
|
|
64
|
+
/** Static capability declaration. */
|
|
65
|
+
readonly capabilities: ProviderCapabilities;
|
|
66
|
+
/**
|
|
67
|
+
* Suggested model id to use when the caller doesn't specify one. Optional
|
|
68
|
+
* because some providers (custom OpenAI-compat without a preset) genuinely
|
|
69
|
+
* don't know — in those cases the caller must supply --model.
|
|
70
|
+
*/
|
|
71
|
+
readonly defaultModel?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Streaming turn. The returned async iterable yields the Anthropic SDK
|
|
74
|
+
* stream-event vocabulary regardless of backend.
|
|
75
|
+
*
|
|
76
|
+
* Implementations should NOT throw for predictable errors (rate limits,
|
|
77
|
+
* auth, network) inside the iterable — instead yield a synthetic event
|
|
78
|
+
* sequence ending in message_stop and let the caller decide. They MAY
|
|
79
|
+
* throw before yielding the first event (e.g. param validation failures).
|
|
80
|
+
*/
|
|
81
|
+
streamMessage(params: MessageStreamParams | MessageCreateParamsStreaming): Promise<AsyncIterable<RawMessageStreamEvent>>;
|
|
82
|
+
/** Non-streaming variant. Default implementation in BaseProvider collects the stream. */
|
|
83
|
+
createMessage(params: MessageStreamParams): Promise<Message>;
|
|
84
|
+
/** Lightweight reachability probe. Called by Selector on startup and by /provider health. */
|
|
85
|
+
healthCheck(): Promise<HealthCheckResult>;
|
|
86
|
+
/** Release any held resources (sockets, browser contexts, etc.). */
|
|
87
|
+
close(): Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Shared base for providers. Gives them a default createMessage that just
|
|
91
|
+
* collects the stream — saves boilerplate while letting any provider override
|
|
92
|
+
* if their backend has a more efficient one-shot path.
|
|
93
|
+
*/
|
|
94
|
+
export declare abstract class BaseProvider implements Provider {
|
|
95
|
+
abstract readonly kind: ProviderKind;
|
|
96
|
+
abstract readonly id: string;
|
|
97
|
+
abstract readonly displayName: string;
|
|
98
|
+
abstract readonly capabilities: ProviderCapabilities;
|
|
99
|
+
readonly defaultModel?: string;
|
|
100
|
+
protected logger: Logger;
|
|
101
|
+
constructor(logger: Logger);
|
|
102
|
+
abstract streamMessage(params: MessageStreamParams | MessageCreateParamsStreaming): Promise<AsyncIterable<RawMessageStreamEvent>>;
|
|
103
|
+
createMessage(params: MessageStreamParams): Promise<Message>;
|
|
104
|
+
abstract healthCheck(): Promise<HealthCheckResult>;
|
|
105
|
+
close(): Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Fold a RawMessageStreamEvent iterable into a complete Message. Used by the
|
|
109
|
+
* default non-streaming path and by tests.
|
|
110
|
+
*
|
|
111
|
+
* Spec: https://docs.anthropic.com/en/api/messages-streaming
|
|
112
|
+
*/
|
|
113
|
+
export declare function collectStreamToMessage(events: AsyncIterable<RawMessageStreamEvent>): Promise<Message>;
|
|
114
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider abstraction.
|
|
3
|
+
*
|
|
4
|
+
* BBClaw's agent runtime speaks one internal protocol: the type vocabulary of
|
|
5
|
+
* the official Anthropic SDK (Message, MessageParam, RawMessageStreamEvent,
|
|
6
|
+
* etc). We use those types because they're a published npm package and they
|
|
7
|
+
* happen to be the most expressive of the major LLM schemas (content blocks,
|
|
8
|
+
* tool_use, thinking, cache_control all model the world we care about).
|
|
9
|
+
*
|
|
10
|
+
* Non-Anthropic providers translate to/from these types at their own
|
|
11
|
+
* boundaries — see openai-compat/requestTranslate.ts and streamAdapter.ts.
|
|
12
|
+
*/
|
|
13
|
+
export const FAIL_CLOSED_CAPABILITIES = {
|
|
14
|
+
nativeTools: false,
|
|
15
|
+
promptCaching: false,
|
|
16
|
+
extendedThinking: false,
|
|
17
|
+
vision: false,
|
|
18
|
+
contextWindow: 8_000,
|
|
19
|
+
maxOutputTokens: 4_096,
|
|
20
|
+
streaming: false,
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Shared base for providers. Gives them a default createMessage that just
|
|
24
|
+
* collects the stream — saves boilerplate while letting any provider override
|
|
25
|
+
* if their backend has a more efficient one-shot path.
|
|
26
|
+
*/
|
|
27
|
+
export class BaseProvider {
|
|
28
|
+
defaultModel;
|
|
29
|
+
logger;
|
|
30
|
+
constructor(logger) {
|
|
31
|
+
this.logger = logger;
|
|
32
|
+
}
|
|
33
|
+
async createMessage(params) {
|
|
34
|
+
const stream = await this.streamMessage(params);
|
|
35
|
+
return collectStreamToMessage(stream);
|
|
36
|
+
}
|
|
37
|
+
async close() {
|
|
38
|
+
// default: nothing held
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Fold a RawMessageStreamEvent iterable into a complete Message. Used by the
|
|
43
|
+
* default non-streaming path and by tests.
|
|
44
|
+
*
|
|
45
|
+
* Spec: https://docs.anthropic.com/en/api/messages-streaming
|
|
46
|
+
*/
|
|
47
|
+
export async function collectStreamToMessage(events) {
|
|
48
|
+
let message = null;
|
|
49
|
+
// Per-index buffers. Each content block has its own delta stream.
|
|
50
|
+
const textBuffers = new Map();
|
|
51
|
+
const toolUseBuffers = new Map();
|
|
52
|
+
const thinkingBuffers = new Map();
|
|
53
|
+
for await (const event of events) {
|
|
54
|
+
switch (event.type) {
|
|
55
|
+
case 'message_start':
|
|
56
|
+
message = event.message;
|
|
57
|
+
break;
|
|
58
|
+
case 'content_block_start': {
|
|
59
|
+
const block = event.content_block;
|
|
60
|
+
if (block.type === 'text') {
|
|
61
|
+
textBuffers.set(event.index, block.text ?? '');
|
|
62
|
+
}
|
|
63
|
+
else if (block.type === 'tool_use') {
|
|
64
|
+
toolUseBuffers.set(event.index, {
|
|
65
|
+
id: block.id,
|
|
66
|
+
name: block.name,
|
|
67
|
+
input: '',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else if (block.type === 'thinking') {
|
|
71
|
+
thinkingBuffers.set(event.index, {
|
|
72
|
+
text: block.thinking ?? '',
|
|
73
|
+
signature: block.signature ?? '',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
case 'content_block_delta': {
|
|
79
|
+
const delta = event.delta;
|
|
80
|
+
if (delta.type === 'text_delta') {
|
|
81
|
+
textBuffers.set(event.index, (textBuffers.get(event.index) ?? '') + delta.text);
|
|
82
|
+
}
|
|
83
|
+
else if (delta.type === 'input_json_delta') {
|
|
84
|
+
const buf = toolUseBuffers.get(event.index);
|
|
85
|
+
if (buf)
|
|
86
|
+
buf.input += delta.partial_json;
|
|
87
|
+
}
|
|
88
|
+
else if (delta.type === 'thinking_delta') {
|
|
89
|
+
const buf = thinkingBuffers.get(event.index);
|
|
90
|
+
if (buf)
|
|
91
|
+
buf.text += delta.thinking;
|
|
92
|
+
}
|
|
93
|
+
else if (delta.type === 'signature_delta') {
|
|
94
|
+
const buf = thinkingBuffers.get(event.index);
|
|
95
|
+
if (buf)
|
|
96
|
+
buf.signature += delta.signature;
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case 'content_block_stop':
|
|
101
|
+
// nothing — accumulators are kept until message_stop
|
|
102
|
+
break;
|
|
103
|
+
case 'message_delta':
|
|
104
|
+
if (message) {
|
|
105
|
+
message.stop_reason = event.delta.stop_reason ?? message.stop_reason;
|
|
106
|
+
message.stop_sequence = event.delta.stop_sequence ?? message.stop_sequence;
|
|
107
|
+
// usage in message_delta is OUTPUT-only per spec; merge carefully
|
|
108
|
+
if (event.usage) {
|
|
109
|
+
message.usage = {
|
|
110
|
+
...message.usage,
|
|
111
|
+
output_tokens: event.usage.output_tokens,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
case 'message_stop':
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (!message)
|
|
121
|
+
throw new Error('collectStreamToMessage: stream ended without message_start');
|
|
122
|
+
// Assemble content blocks in order. We sort by the indices we saw.
|
|
123
|
+
const allIndices = new Set([
|
|
124
|
+
...textBuffers.keys(),
|
|
125
|
+
...toolUseBuffers.keys(),
|
|
126
|
+
...thinkingBuffers.keys(),
|
|
127
|
+
]);
|
|
128
|
+
const sorted = [...allIndices].sort((a, b) => a - b);
|
|
129
|
+
const content = sorted.map((idx) => {
|
|
130
|
+
if (textBuffers.has(idx)) {
|
|
131
|
+
return { type: 'text', text: textBuffers.get(idx) ?? '', citations: null };
|
|
132
|
+
}
|
|
133
|
+
if (toolUseBuffers.has(idx)) {
|
|
134
|
+
const tu = toolUseBuffers.get(idx);
|
|
135
|
+
let input = {};
|
|
136
|
+
try {
|
|
137
|
+
input = tu.input ? JSON.parse(tu.input) : {};
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// Malformed JSON from a misbehaving backend; surface the raw text so the
|
|
141
|
+
// caller can decide what to do (rather than silently dropping it).
|
|
142
|
+
input = { _malformed: tu.input };
|
|
143
|
+
}
|
|
144
|
+
return { type: 'tool_use', id: tu.id, name: tu.name, input };
|
|
145
|
+
}
|
|
146
|
+
const th = thinkingBuffers.get(idx);
|
|
147
|
+
return { type: 'thinking', thinking: th.text, signature: th.signature };
|
|
148
|
+
});
|
|
149
|
+
message.content = content;
|
|
150
|
+
return message;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek web-bridge spec.
|
|
3
|
+
*
|
|
4
|
+
* Targets chat.deepseek.com. Selectors use attribute-CONTAINS matching
|
|
5
|
+
* instead of exact class names — DeepSeek's frontend ships hashed class
|
|
6
|
+
* names that change on every deploy, but a few semantic prefixes are
|
|
7
|
+
* stable: `ds-message`, `ds-markdown`, `ds-think-content`.
|
|
8
|
+
*
|
|
9
|
+
* DOM shape as of 2026-05 (verified via scripts/probe-deepseek-dom.ts):
|
|
10
|
+
* - Each turn is wrapped in `.ds-message` (used for BOTH user + assistant).
|
|
11
|
+
* - Assistant's answer content lives in `.ds-markdown` inside that wrapper.
|
|
12
|
+
* - Assistant's chain-of-thought lives in `.ds-think-content` (filtered out
|
|
13
|
+
* by the observer's reasoning heuristic).
|
|
14
|
+
* - User messages have no `.ds-markdown` child — distinguished via :not(:has()).
|
|
15
|
+
*
|
|
16
|
+
* If DeepSeek ever rebrands these completely, this file is the recovery
|
|
17
|
+
* point. Re-run scripts/probe-deepseek-dom.ts to discover the new classes
|
|
18
|
+
* and update below.
|
|
19
|
+
*/
|
|
20
|
+
import type { WebBridgeSpec } from '../shared/types.js';
|
|
21
|
+
export declare const DEEPSEEK_WEB_SPEC: WebBridgeSpec;
|
|
22
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../../../src/providers/web-bridge/deepseek/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEvD,eAAO,MAAM,iBAAiB,EAAE,aAyD/B,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek web-bridge spec.
|
|
3
|
+
*
|
|
4
|
+
* Targets chat.deepseek.com. Selectors use attribute-CONTAINS matching
|
|
5
|
+
* instead of exact class names — DeepSeek's frontend ships hashed class
|
|
6
|
+
* names that change on every deploy, but a few semantic prefixes are
|
|
7
|
+
* stable: `ds-message`, `ds-markdown`, `ds-think-content`.
|
|
8
|
+
*
|
|
9
|
+
* DOM shape as of 2026-05 (verified via scripts/probe-deepseek-dom.ts):
|
|
10
|
+
* - Each turn is wrapped in `.ds-message` (used for BOTH user + assistant).
|
|
11
|
+
* - Assistant's answer content lives in `.ds-markdown` inside that wrapper.
|
|
12
|
+
* - Assistant's chain-of-thought lives in `.ds-think-content` (filtered out
|
|
13
|
+
* by the observer's reasoning heuristic).
|
|
14
|
+
* - User messages have no `.ds-markdown` child — distinguished via :not(:has()).
|
|
15
|
+
*
|
|
16
|
+
* If DeepSeek ever rebrands these completely, this file is the recovery
|
|
17
|
+
* point. Re-run scripts/probe-deepseek-dom.ts to discover the new classes
|
|
18
|
+
* and update below.
|
|
19
|
+
*/
|
|
20
|
+
export const DEEPSEEK_WEB_SPEC = {
|
|
21
|
+
serviceId: 'deepseek-web',
|
|
22
|
+
displayName: 'DeepSeek (Web Bridge)',
|
|
23
|
+
homeUrl: 'https://chat.deepseek.com',
|
|
24
|
+
selectors: {
|
|
25
|
+
composer: 'textarea',
|
|
26
|
+
// Assistant's rendered answer. ds-markdown is the stable semantic class
|
|
27
|
+
// even though it ships alongside hashed siblings.
|
|
28
|
+
responseRoot: '.ds-markdown',
|
|
29
|
+
// .ds-message wraps BOTH user and assistant turns — we use it as a
|
|
30
|
+
// turn-boundary signal, not as a strict user-only selector. We tried
|
|
31
|
+
// `.ds-message:not(:has(.ds-markdown))` to isolate user messages, but
|
|
32
|
+
// there's a brief window where the assistant's outer `.ds-message`
|
|
33
|
+
// exists before its inner `.ds-markdown` is mounted — the selector
|
|
34
|
+
// briefly matches it, then stops matching, which made the observer's
|
|
35
|
+
// count-down branch move turnStartIdx past the assistant's content and
|
|
36
|
+
// silently lose all streaming text. Counting any `.ds-message` change
|
|
37
|
+
// as a turn boundary is racier-but-correct: prevResponseText resets,
|
|
38
|
+
// and turnStartIdx only advances at signal points we trust.
|
|
39
|
+
userMessage: '.ds-message',
|
|
40
|
+
},
|
|
41
|
+
// Try a ladder of locator strategies — each one returns a Playwright Locator.
|
|
42
|
+
// The adapter calls .click() on each in order and falls back to URL
|
|
43
|
+
// navigation if all of them throw. Order matters: most specific first,
|
|
44
|
+
// most generic last.
|
|
45
|
+
newChatStrategies: [
|
|
46
|
+
(page) => page
|
|
47
|
+
.getByRole('button', {
|
|
48
|
+
name: /新对话|新建对话|new chat|new conversation|开启新对话/i,
|
|
49
|
+
})
|
|
50
|
+
.first(),
|
|
51
|
+
(page) => page.getByRole('link', { name: /新对话|新建对话|new chat/i }).first(),
|
|
52
|
+
(page) => page.locator('button:has-text("新对话")').first(),
|
|
53
|
+
(page) => page.locator('button:has-text("新建对话")').first(),
|
|
54
|
+
(page) => page.locator('button:has-text("New chat")').first(),
|
|
55
|
+
(page) => page.locator('[role="button"]:has-text("新对话")').first(),
|
|
56
|
+
(page) => page.locator('a:has-text("新对话")').first(),
|
|
57
|
+
(page) => page
|
|
58
|
+
.locator('button[aria-label*="新对话"], button[aria-label*="新建"], button[aria-label*="new" i]')
|
|
59
|
+
.first(),
|
|
60
|
+
],
|
|
61
|
+
// DeepSeek doesn't deploy aggressive bot detection (it's a logged-in flow
|
|
62
|
+
// for free users, and they treat the website as a product surface for
|
|
63
|
+
// their own users). Standard Chromium is sufficient.
|
|
64
|
+
stealthLevel: 'off',
|
|
65
|
+
// DeepSeek-V3 / R1 advertise 128k but the WEB UI's accepted input is
|
|
66
|
+
// smaller — somewhere around 32-64k in practice before the message gets
|
|
67
|
+
// truncated. Be conservative.
|
|
68
|
+
contextWindowEstimate: 32_000,
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../../../src/providers/web-bridge/deepseek/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,SAAS,EAAE,cAAc;IACzB,WAAW,EAAE,uBAAuB;IACpC,OAAO,EAAE,2BAA2B;IAEpC,SAAS,EAAE;QACT,QAAQ,EAAE,UAAU;QACpB,wEAAwE;QACxE,kDAAkD;QAClD,YAAY,EAAE,cAAc;QAC5B,mEAAmE;QACnE,qEAAqE;QACrE,sEAAsE;QACtE,mEAAmE;QACnE,mEAAmE;QACnE,qEAAqE;QACrE,uEAAuE;QACvE,sEAAsE;QACtE,qEAAqE;QACrE,4DAA4D;QAC5D,WAAW,EAAE,aAAa;KAC3B;IAED,8EAA8E;IAC9E,oEAAoE;IACpE,uEAAuE;IACvE,qBAAqB;IACrB,iBAAiB,EAAE;QACjB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI;aACD,SAAS,CAAC,QAAQ,EAAE;YACnB,IAAI,EAAE,2CAA2C;SAClD,CAAC;aACD,KAAK,EAAE;QACZ,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC,CAAC,KAAK,EAAE;QACxE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,KAAK,EAAE;QACxD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE;QACzD,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE;QAC7D,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,KAAK,EAAE;QACjE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE;QACnD,CAAC,IAAI,EAAE,EAAE,CACP,IAAI;aACD,OAAO,CACN,kFAAkF,CACnF;aACA,KAAK,EAAE;KACb;IAED,0EAA0E;IAC1E,sEAAsE;IACtE,qDAAqD;IACrD,YAAY,EAAE,KAAK;IAEnB,qEAAqE;IACrE,wEAAwE;IACxE,8BAA8B;IAC9B,qBAAqB,EAAE,MAAM;CAC9B,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize an Anthropic-shaped message history into a single text prompt
|
|
3
|
+
* that web-bridge chat services can ingest.
|
|
4
|
+
*
|
|
5
|
+
* Decision: send the COMPLETE history every turn (after clicking "new chat")
|
|
6
|
+
* rather than reuse the service's own chat session. Reasons:
|
|
7
|
+
* - Upper layers (microcompact, fork-agent, history rewrites) treat
|
|
8
|
+
* messages[] as the source of truth and routinely mutate it. The
|
|
9
|
+
* service's internal chat state would diverge.
|
|
10
|
+
* - Reusing chat state would also conflict with the agent's "tool_result"
|
|
11
|
+
* pattern: we'd have to stuff tool results into user turns anyway.
|
|
12
|
+
*
|
|
13
|
+
* The serialized prompt is structured so it parses well visually AND models
|
|
14
|
+
* see clear turn boundaries. Format:
|
|
15
|
+
*
|
|
16
|
+
* [Optional system block]
|
|
17
|
+
* [Tool protocol instructions]
|
|
18
|
+
*
|
|
19
|
+
* ──── Conversation history ────
|
|
20
|
+
*
|
|
21
|
+
* User:
|
|
22
|
+
* ...
|
|
23
|
+
*
|
|
24
|
+
* Assistant:
|
|
25
|
+
* ...
|
|
26
|
+
*
|
|
27
|
+
* [Tool result for Bash]:
|
|
28
|
+
* ...
|
|
29
|
+
*
|
|
30
|
+
* ──── Current turn ────
|
|
31
|
+
*
|
|
32
|
+
* User:
|
|
33
|
+
* <latest user message>
|
|
34
|
+
*
|
|
35
|
+
* Assistant:
|
|
36
|
+
*
|
|
37
|
+
* Empty "Assistant:" trailing prompt nudges the model to continue rather
|
|
38
|
+
* than echo the structure back.
|
|
39
|
+
*/
|
|
40
|
+
import type { MessageCreateParamsBase } from '@anthropic-ai/sdk/resources/messages/messages.js';
|
|
41
|
+
export interface SerializeOptions {
|
|
42
|
+
/**
|
|
43
|
+
* When the most recent message is the user's current turn, render it under
|
|
44
|
+
* the "Current turn" header. Default: true.
|
|
45
|
+
*/
|
|
46
|
+
separateCurrentTurn?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare function serializeHistory(params: MessageCreateParamsBase, opts?: SerializeOptions): string;
|
|
49
|
+
//# sourceMappingURL=historySerializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historySerializer.d.ts","sourceRoot":"","sources":["../../../src/providers/web-bridge/historySerializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAEV,uBAAuB,EAKxB,MAAM,kDAAkD,CAAA;AAiBzD,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,uBAAuB,EAC/B,IAAI,GAAE,gBAAqB,GAC1B,MAAM,CAsCR"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize an Anthropic-shaped message history into a single text prompt
|
|
3
|
+
* that web-bridge chat services can ingest.
|
|
4
|
+
*
|
|
5
|
+
* Decision: send the COMPLETE history every turn (after clicking "new chat")
|
|
6
|
+
* rather than reuse the service's own chat session. Reasons:
|
|
7
|
+
* - Upper layers (microcompact, fork-agent, history rewrites) treat
|
|
8
|
+
* messages[] as the source of truth and routinely mutate it. The
|
|
9
|
+
* service's internal chat state would diverge.
|
|
10
|
+
* - Reusing chat state would also conflict with the agent's "tool_result"
|
|
11
|
+
* pattern: we'd have to stuff tool results into user turns anyway.
|
|
12
|
+
*
|
|
13
|
+
* The serialized prompt is structured so it parses well visually AND models
|
|
14
|
+
* see clear turn boundaries. Format:
|
|
15
|
+
*
|
|
16
|
+
* [Optional system block]
|
|
17
|
+
* [Tool protocol instructions]
|
|
18
|
+
*
|
|
19
|
+
* ──── Conversation history ────
|
|
20
|
+
*
|
|
21
|
+
* User:
|
|
22
|
+
* ...
|
|
23
|
+
*
|
|
24
|
+
* Assistant:
|
|
25
|
+
* ...
|
|
26
|
+
*
|
|
27
|
+
* [Tool result for Bash]:
|
|
28
|
+
* ...
|
|
29
|
+
*
|
|
30
|
+
* ──── Current turn ────
|
|
31
|
+
*
|
|
32
|
+
* User:
|
|
33
|
+
* <latest user message>
|
|
34
|
+
*
|
|
35
|
+
* Assistant:
|
|
36
|
+
*
|
|
37
|
+
* Empty "Assistant:" trailing prompt nudges the model to continue rather
|
|
38
|
+
* than echo the structure back.
|
|
39
|
+
*/
|
|
40
|
+
import { ARG_CLOSE, ARG_OPEN_PREFIX, ARG_OPEN_SUFFIX, TOOL_NAME_CLOSE, TOOL_NAME_OPEN, TOOL_USE_CLOSE, TOOL_USE_OPEN, buildToolProtocolPrompt, escapeArgContent, } from './promptInjector.js';
|
|
41
|
+
const SECTION_DIVIDER = '\n\n───────────────────────────────────────\n\n';
|
|
42
|
+
const HISTORY_HEADER = `${SECTION_DIVIDER}Conversation history${SECTION_DIVIDER}`;
|
|
43
|
+
const CURRENT_HEADER = `${SECTION_DIVIDER}Current turn${SECTION_DIVIDER}`;
|
|
44
|
+
export function serializeHistory(params, opts = {}) {
|
|
45
|
+
const sep = opts.separateCurrentTurn !== false;
|
|
46
|
+
const parts = [];
|
|
47
|
+
// 1. System content (if any)
|
|
48
|
+
const sysText = renderSystem(params.system);
|
|
49
|
+
if (sysText)
|
|
50
|
+
parts.push(sysText);
|
|
51
|
+
// 2. Tool protocol explanation (also includes tool descriptions)
|
|
52
|
+
const protocolText = buildToolProtocolPrompt(params.tools);
|
|
53
|
+
if (protocolText)
|
|
54
|
+
parts.push(protocolText);
|
|
55
|
+
// 3. History / current turn
|
|
56
|
+
const messages = params.messages;
|
|
57
|
+
if (messages.length === 0) {
|
|
58
|
+
// Edge case: no messages. Just return the system + protocol.
|
|
59
|
+
return parts.join('\n\n').trim();
|
|
60
|
+
}
|
|
61
|
+
// Split off the current (last) message if it's the user's, so we can show
|
|
62
|
+
// it under a clear "current" header.
|
|
63
|
+
const last = messages[messages.length - 1];
|
|
64
|
+
const isLastUser = !!last && last.role === 'user';
|
|
65
|
+
const history = sep && isLastUser ? messages.slice(0, -1) : messages;
|
|
66
|
+
if (history.length > 0) {
|
|
67
|
+
parts.push(HISTORY_HEADER + history.map(renderMessage).join('\n\n'));
|
|
68
|
+
}
|
|
69
|
+
if (sep && isLastUser && last) {
|
|
70
|
+
parts.push(`${CURRENT_HEADER}${renderMessage(last)}\n\nAssistant:`);
|
|
71
|
+
}
|
|
72
|
+
else if (!sep) {
|
|
73
|
+
// Without the split, append the trailing "Assistant:" cue if the last
|
|
74
|
+
// message is from the user.
|
|
75
|
+
if (isLastUser)
|
|
76
|
+
parts.push('Assistant:');
|
|
77
|
+
}
|
|
78
|
+
return parts.join('\n\n').trim();
|
|
79
|
+
}
|
|
80
|
+
// ----- helpers -----
|
|
81
|
+
function renderSystem(system) {
|
|
82
|
+
if (!system)
|
|
83
|
+
return '';
|
|
84
|
+
if (typeof system === 'string')
|
|
85
|
+
return system.trim();
|
|
86
|
+
return system.map((b) => b.text).join('\n\n').trim();
|
|
87
|
+
}
|
|
88
|
+
function renderMessage(m) {
|
|
89
|
+
const label = m.role === 'user' ? 'User' : 'Assistant';
|
|
90
|
+
const body = typeof m.content === 'string' ? m.content : renderBlocks(m.content, m.role);
|
|
91
|
+
return `${label}:\n${body.trim()}`;
|
|
92
|
+
}
|
|
93
|
+
function renderBlocks(blocks, role) {
|
|
94
|
+
const pieces = [];
|
|
95
|
+
for (const b of blocks) {
|
|
96
|
+
if (b.type === 'text') {
|
|
97
|
+
pieces.push(b.text);
|
|
98
|
+
}
|
|
99
|
+
else if (b.type === 'tool_use' && role === 'assistant') {
|
|
100
|
+
pieces.push(renderToolUseAsXml(b));
|
|
101
|
+
}
|
|
102
|
+
else if (b.type === 'tool_result' && role === 'user') {
|
|
103
|
+
pieces.push(renderToolResult(b));
|
|
104
|
+
}
|
|
105
|
+
else if (b.type === 'image') {
|
|
106
|
+
// Web bridges don't accept image uploads via this path; flag clearly.
|
|
107
|
+
pieces.push('[image omitted — web bridge does not support image uploads in this mode]');
|
|
108
|
+
}
|
|
109
|
+
else if (b.type === 'thinking') {
|
|
110
|
+
// Don't echo reasoning into the prompt — it's the model's own scratch
|
|
111
|
+
// space; sending it back would be circular and bloat the context.
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return pieces.join('\n\n').trim();
|
|
116
|
+
}
|
|
117
|
+
function renderToolUseAsXml(b) {
|
|
118
|
+
// Re-encode the assistant's prior tool call into the same arg-tag format
|
|
119
|
+
// the model is asked to emit. This keeps the history visually consistent
|
|
120
|
+
// with the on-protocol output and reinforces the protocol by example.
|
|
121
|
+
const lines = [TOOL_USE_OPEN, `${TOOL_NAME_OPEN}${b.name}${TOOL_NAME_CLOSE}`];
|
|
122
|
+
const input = (b.input ?? {});
|
|
123
|
+
for (const [k, v] of Object.entries(input)) {
|
|
124
|
+
const raw = typeof v === 'string' ? v : JSON.stringify(v);
|
|
125
|
+
const escaped = escapeArgContent(raw);
|
|
126
|
+
// Match the multi-line style the prompt teaches: tag on its own line if
|
|
127
|
+
// the value contains a newline, otherwise compact on one line.
|
|
128
|
+
if (escaped.includes('\n')) {
|
|
129
|
+
lines.push(`${ARG_OPEN_PREFIX}${k}${ARG_OPEN_SUFFIX}`, escaped, ARG_CLOSE);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
lines.push(`${ARG_OPEN_PREFIX}${k}${ARG_OPEN_SUFFIX}${escaped}${ARG_CLOSE}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
lines.push(TOOL_USE_CLOSE);
|
|
136
|
+
return lines.join('\n');
|
|
137
|
+
}
|
|
138
|
+
function renderToolResult(b) {
|
|
139
|
+
const body = typeof b.content === 'string'
|
|
140
|
+
? b.content
|
|
141
|
+
: Array.isArray(b.content)
|
|
142
|
+
? b.content
|
|
143
|
+
.map((p) => (p.type === 'text' ? p.text : p.type === 'image' ? '[image]' : ''))
|
|
144
|
+
.join('\n')
|
|
145
|
+
: '';
|
|
146
|
+
const prefix = b.is_error ? '[Tool ERROR' : '[Tool result';
|
|
147
|
+
// We don't know the tool name from the result block alone (only tool_use_id);
|
|
148
|
+
// upper layer could pass a name map if it cared, but the id pairing is
|
|
149
|
+
// usually obvious from the immediately preceding tool_use in the history.
|
|
150
|
+
return `${prefix} for ${b.tool_use_id}]:\n${body.trim()}`;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=historySerializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historySerializer.js","sourceRoot":"","sources":["../../../src/providers/web-bridge/historySerializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Public surface of the web-bridge subsystem. */
|
|
2
|
+
export { WebBridgeProvider, type WebBridgeProviderOptions } from './provider.js';
|
|
3
|
+
export { WebBridgeAdapter, type WebBridgeAdapterOptions } from './shared/WebBridgeAdapter.js';
|
|
4
|
+
export { BrowserSession, type BrowserSessionOptions } from './shared/BrowserSession.js';
|
|
5
|
+
export { type WebBridgeSpec, type WebBridgeState, type WebBridgeSelectors, type ResponseTextListener, type ExternalUserMessageListener, type StateChangeListener, BridgeLoginRequiredError, BridgeDOMUnrecognizedError, } from './shared/types.js';
|
|
6
|
+
export { DEEPSEEK_WEB_SPEC } from './deepseek/spec.js';
|
|
7
|
+
export { buildToolProtocolPrompt, TOOL_USE_OPEN, TOOL_USE_CLOSE, TOOL_NAME_OPEN, TOOL_NAME_CLOSE, ARG_OPEN_PREFIX, ARG_OPEN_SUFFIX, ARG_CLOSE, ARG_CLOSE_ESCAPE_TOKEN, escapeArgContent, unescapeArgContent, } from './promptInjector.js';
|
|
8
|
+
export { ToolUseStreamParser } from './toolUseParser.js';
|
|
9
|
+
export { serializeHistory, type SerializeOptions } from './historySerializer.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/web-bridge/index.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAA;AAChF,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACvF,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,SAAS,EACT,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Public surface of the web-bridge subsystem. */
|
|
2
|
+
export { WebBridgeProvider } from './provider.js';
|
|
3
|
+
export { WebBridgeAdapter } from './shared/WebBridgeAdapter.js';
|
|
4
|
+
export { BrowserSession } from './shared/BrowserSession.js';
|
|
5
|
+
export { BridgeLoginRequiredError, BridgeDOMUnrecognizedError, } from './shared/types.js';
|
|
6
|
+
export { DEEPSEEK_WEB_SPEC } from './deepseek/spec.js';
|
|
7
|
+
export { buildToolProtocolPrompt, TOOL_USE_OPEN, TOOL_USE_CLOSE, TOOL_NAME_OPEN, TOOL_NAME_CLOSE, ARG_OPEN_PREFIX, ARG_OPEN_SUFFIX, ARG_CLOSE, ARG_CLOSE_ESCAPE_TOKEN, escapeArgContent, unescapeArgContent, } from './promptInjector.js';
|
|
8
|
+
export { ToolUseStreamParser } from './toolUseParser.js';
|
|
9
|
+
export { serializeHistory } from './historySerializer.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/web-bridge/index.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,iBAAiB,EAAiC,MAAM,eAAe,CAAA;AAChF,OAAO,EAAE,gBAAgB,EAAgC,MAAM,8BAA8B,CAAA;AAC7F,OAAO,EAAE,cAAc,EAA8B,MAAM,4BAA4B,CAAA;AACvF,OAAO,EAOL,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,SAAS,EACT,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAyB,MAAM,wBAAwB,CAAA"}
|