@bubblebrain-ai/bubble 0.0.53 → 0.0.55
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 +43 -0
- package/dist/agent/input-controller.d.ts +3 -0
- package/dist/agent/input-controller.js +13 -0
- package/dist/agent.js +7 -1
- package/dist/model-catalog.js +7 -2
- package/dist/model-pricing.d.ts +1 -5
- package/dist/model-pricing.js +0 -0
- package/dist/provider-ai-sdk.js +5 -0
- package/dist/provider-registry.js +34 -10
- package/dist/sdk/index.d.ts +97 -6
- package/dist/sdk/index.js +445 -34
- package/dist/sdk/replay-event-log.d.ts +19 -0
- package/dist/sdk/replay-event-log.js +72 -0
- package/dist/sdk/session-turn-coordinator.d.ts +45 -0
- package/dist/sdk/session-turn-coordinator.js +227 -0
- package/dist/tui/app.js +5 -3
- package/dist/tui/controller/controller.js +12 -6
- package/dist/tui/fullscreen.js +2 -1
- package/dist/types.d.ts +11 -1
- package/dist/update/index.d.ts +1 -0
- package/dist/update/index.js +22 -17
- package/package.json +5 -3
- /package/{packages/pi-tui/node_modules → node_modules}/marked/LICENSE +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/README.md +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/bin/main.js +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/bin/marked.js +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/lib/marked.d.ts +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/lib/marked.esm.js +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/lib/marked.esm.js.map +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/lib/marked.umd.js +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/lib/marked.umd.js.map +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/man/marked.1 +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/man/marked.1.md +0 -0
- /package/{packages/pi-tui/node_modules → node_modules}/marked/package.json +0 -0
package/README.md
CHANGED
|
@@ -67,6 +67,49 @@ Resume your last conversation:
|
|
|
67
67
|
bubble --resume
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
## Embed with the SDK
|
|
71
|
+
|
|
72
|
+
The npm package exports `BubbleSdk` from both `@bubblebrain-ai/bubble` and
|
|
73
|
+
`@bubblebrain-ai/bubble/sdk`. Turns are serialized FIFO within one session and
|
|
74
|
+
remain parallel across different sessions.
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { BubbleSdk } from "@bubblebrain-ai/bubble/sdk";
|
|
78
|
+
|
|
79
|
+
const sdk = new BubbleSdk({ defaultCwd: process.cwd() });
|
|
80
|
+
const session = sdk.createSession();
|
|
81
|
+
const events = sdk.runTurn(session.id, { prompt: "Inspect this project" });
|
|
82
|
+
|
|
83
|
+
for await (const event of events) {
|
|
84
|
+
if (event.type === "text_delta") process.stdout.write(event.content);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const queued = sdk.enqueueTurn(session.id, { prompt: "Run the tests next" });
|
|
88
|
+
void (async () => {
|
|
89
|
+
for await (const event of queued) {
|
|
90
|
+
// Render the queued turn's events.
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
While a turn owns the session slot, `sdk.steer(session.id, text)` adds text at
|
|
96
|
+
the next model-call boundary and returns a receipt: `steered` (injected into
|
|
97
|
+
the active turn), `queued` (the session is idle or the active turn can no
|
|
98
|
+
longer accept input, so the text becomes the next FIFO turn automatically),
|
|
99
|
+
or `rejected`. Every accepted receipt includes an `outcome` promise that
|
|
100
|
+
settles exactly once to `input_applied`, `input_queued`, or `input_rejected` —
|
|
101
|
+
even if the host drops the event iterator early.
|
|
102
|
+
|
|
103
|
+
Turns are driven by the SDK itself, not by iterator consumption: a returned
|
|
104
|
+
iterator is a replay subscription, so dropping it never stalls or cancels the
|
|
105
|
+
turn. `openSession(sessionId)` returns a durable handle whose `events` iterable
|
|
106
|
+
replays the whole session log from sequence 1 and `eventsFrom(n)` resumes after
|
|
107
|
+
the last sequence the host durably processed. `stop(sessionId)` is
|
|
108
|
+
Claude-style: it interrupts the active turn and keeps the queue; pass
|
|
109
|
+
`{ cancelQueued: true }` to clear both. `clearQueue(sessionId)` cancels only
|
|
110
|
+
queued turns, and `deleteSession(sessionId)` awaits teardown before the JSONL
|
|
111
|
+
file is removed.
|
|
112
|
+
|
|
70
113
|
## Model providers
|
|
71
114
|
|
|
72
115
|
Bubble ships with a catalog of built-in providers. Configure them inside the app — no environment variables required.
|
|
@@ -3,9 +3,12 @@ export declare class AgentRunInputQueue implements AgentInputController {
|
|
|
3
3
|
private readonly idPrefix;
|
|
4
4
|
private pending;
|
|
5
5
|
private nextInputId;
|
|
6
|
+
private accepting;
|
|
6
7
|
constructor(idPrefix?: string);
|
|
7
8
|
enqueue(content: string): AgentRunInput;
|
|
9
|
+
tryEnqueue(content: string): AgentRunInput | undefined;
|
|
8
10
|
drainPendingInputs(): AgentRunInput[];
|
|
9
11
|
pendingInputCount(): number;
|
|
10
12
|
clear(): AgentRunInput[];
|
|
13
|
+
closePendingInputs(): AgentRunInput[];
|
|
11
14
|
}
|
|
@@ -2,10 +2,19 @@ export class AgentRunInputQueue {
|
|
|
2
2
|
idPrefix;
|
|
3
3
|
pending = [];
|
|
4
4
|
nextInputId = 0;
|
|
5
|
+
accepting = true;
|
|
5
6
|
constructor(idPrefix = "input") {
|
|
6
7
|
this.idPrefix = idPrefix;
|
|
7
8
|
}
|
|
8
9
|
enqueue(content) {
|
|
10
|
+
const input = this.tryEnqueue(content);
|
|
11
|
+
if (!input)
|
|
12
|
+
throw new Error("Agent input queue is closed");
|
|
13
|
+
return input;
|
|
14
|
+
}
|
|
15
|
+
tryEnqueue(content) {
|
|
16
|
+
if (!this.accepting)
|
|
17
|
+
return undefined;
|
|
9
18
|
const input = {
|
|
10
19
|
id: `${this.idPrefix}-${++this.nextInputId}`,
|
|
11
20
|
content,
|
|
@@ -27,4 +36,8 @@ export class AgentRunInputQueue {
|
|
|
27
36
|
clear() {
|
|
28
37
|
return this.drainPendingInputs();
|
|
29
38
|
}
|
|
39
|
+
closePendingInputs() {
|
|
40
|
+
this.accepting = false;
|
|
41
|
+
return this.drainPendingInputs();
|
|
42
|
+
}
|
|
30
43
|
}
|
package/dist/agent.js
CHANGED
|
@@ -644,7 +644,11 @@ export class Agent {
|
|
|
644
644
|
return events;
|
|
645
645
|
};
|
|
646
646
|
const rejectPendingInputs = async (reason) => {
|
|
647
|
-
|
|
647
|
+
// Seal before the first await. A host can submit in reaction to the final
|
|
648
|
+
// turn boundary; accepting after this drain would orphan that input.
|
|
649
|
+
const pendingInputs = inputController?.closePendingInputs?.()
|
|
650
|
+
?? inputController?.drainPendingInputs()
|
|
651
|
+
?? [];
|
|
648
652
|
if (pendingInputs.length === 0)
|
|
649
653
|
return [];
|
|
650
654
|
const events = [];
|
|
@@ -697,6 +701,8 @@ export class Agent {
|
|
|
697
701
|
yield emit({ type: "turn_start" });
|
|
698
702
|
yield emit({ type: "text_delta", content: message });
|
|
699
703
|
yield emit({ type: "turn_end", willContinue: false });
|
|
704
|
+
for (const event of await rejectPendingInputs("no_continuation"))
|
|
705
|
+
yield emit(event);
|
|
700
706
|
yield emit({ type: "agent_end" });
|
|
701
707
|
return;
|
|
702
708
|
}
|
package/dist/model-catalog.js
CHANGED
|
@@ -87,6 +87,9 @@ const ANTHROPIC_CHAT_LEVELS = ["off"];
|
|
|
87
87
|
const GROK_45_LEVELS = ["low", "medium", "high"];
|
|
88
88
|
const GEMINI_3_LEVELS = ["low", "medium", "high"];
|
|
89
89
|
const GEMINI_3_FLASH_LEVELS = ["minimal", "low", "medium", "high"];
|
|
90
|
+
// Verified against the native API on 2026-09-02: Gemini 3.7/3.8 Flash reject
|
|
91
|
+
// thinkingLevel=minimal but accept thinkingBudget=0 plus low/medium/high.
|
|
92
|
+
const GEMINI_37_38_FLASH_LEVELS = ["off", "low", "medium", "high"];
|
|
90
93
|
const GEMINI_25_PRO_LEVELS = ["low", "medium", "high"];
|
|
91
94
|
const GEMINI_25_FLASH_LEVELS = ["off", "low", "medium", "high"];
|
|
92
95
|
export const BUILTIN_MODELS = [
|
|
@@ -126,8 +129,10 @@ export const BUILTIN_MODELS = [
|
|
|
126
129
|
{ id: "deepseek-v4-pro", name: "deepseek-v4-pro", providerId: "deepseek", tier: "strong", reasoningLevels: DEEPSEEK_V4_LEVELS, defaultReasoningLevel: "high", contextWindow: 1048576 },
|
|
127
130
|
// Offline/no-key fallback only: with an API key the registry replaces this
|
|
128
131
|
// list via fetchGeminiModels (GET /v1beta/models, newest five). Gemini 3
|
|
129
|
-
//
|
|
130
|
-
//
|
|
132
|
+
// thinking support varies by release: 3.7/3.8 Flash support off/low/medium/high
|
|
133
|
+
// while older Flash releases expose minimal/low/medium/high.
|
|
134
|
+
{ id: "gemini-3.8-flash", name: "Gemini 3.8 Flash", providerId: "google", tier: "fast", reasoningLevels: GEMINI_37_38_FLASH_LEVELS, contextWindow: 1048576 },
|
|
135
|
+
{ id: "gemini-3.7-flash", name: "Gemini 3.7 Flash", providerId: "google", tier: "fast", reasoningLevels: GEMINI_37_38_FLASH_LEVELS, contextWindow: 1048576 },
|
|
131
136
|
{ id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", providerId: "google", tier: "fast", reasoningLevels: GEMINI_3_FLASH_LEVELS, contextWindow: 1048576 },
|
|
132
137
|
{ id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro", providerId: "google", tier: "strong", reasoningLevels: GEMINI_3_LEVELS, defaultReasoningLevel: "high", contextWindow: 1048576 },
|
|
133
138
|
{ id: "gemini-3-flash-preview", name: "Gemini 3 Flash", providerId: "google", tier: "fast", reasoningLevels: GEMINI_3_FLASH_LEVELS, contextWindow: 1048576 },
|
package/dist/model-pricing.d.ts
CHANGED
|
@@ -35,11 +35,7 @@ export interface ModelPricing extends ModelPricingRate {
|
|
|
35
35
|
/** Rate used before `effectiveFrom` (for historical session statistics). */
|
|
36
36
|
prior?: ModelPricingRate;
|
|
37
37
|
effectiveUntil?: string;
|
|
38
|
-
original?:
|
|
39
|
-
inputCacheHitPerMillion: number;
|
|
40
|
-
inputCacheMissPerMillion: number;
|
|
41
|
-
outputPerMillion: number;
|
|
42
|
-
};
|
|
38
|
+
original?: ModelPricingRate;
|
|
43
39
|
}
|
|
44
40
|
/**
|
|
45
41
|
* Hand-maintained corrections layered over the generated models.dev snapshot.
|
package/dist/model-pricing.js
CHANGED
|
Binary file
|
package/dist/provider-ai-sdk.js
CHANGED
|
@@ -509,6 +509,11 @@ export function selectLatestGeminiModels(entries, limit = 5) {
|
|
|
509
509
|
export function geminiReasoningLevels(modelId) {
|
|
510
510
|
const version = Number.parseFloat(/^gemini-(\d+(?:\.\d+)?)/.exec(modelId)?.[1] ?? "0");
|
|
511
511
|
const isPro = modelId.includes("-pro");
|
|
512
|
+
// Live probes show 3.7 and 3.8 Flash share this newer ladder. Keep the
|
|
513
|
+
// exception bounded to verified releases instead of guessing for 3.9+.
|
|
514
|
+
if (!isPro && (version === 3.7 || version === 3.8)) {
|
|
515
|
+
return ["off", "low", "medium", "high"];
|
|
516
|
+
}
|
|
512
517
|
if (version >= 3) {
|
|
513
518
|
return isPro ? ["low", "medium", "high"] : ["minimal", "low", "medium", "high"];
|
|
514
519
|
}
|
|
@@ -11,7 +11,7 @@ import { getBubbleHome } from "./bubble-home.js";
|
|
|
11
11
|
import { BUILTIN_PROVIDERS as CATALOG_PROVIDERS, clearDynamicModelMetadata, getBuiltinModel, getBuiltinProvider, inferGrokModelMetadata, listBuiltinModels, replaceDynamicModelMetadata, } from "./model-catalog.js";
|
|
12
12
|
import { ModelConfig } from "./model-config.js";
|
|
13
13
|
import { AuthStorage } from "./oauth/index.js";
|
|
14
|
-
import { fetchGeminiModels } from "./provider-ai-sdk.js";
|
|
14
|
+
import { fetchGeminiModels, geminiReasoningLevels } from "./provider-ai-sdk.js";
|
|
15
15
|
import { extractChatGptAccountId, fetchOpenAICodexModelCatalog } from "./provider-openai-codex.js";
|
|
16
16
|
import { fetchGrokSubscriptionModels } from "./provider-grok.js";
|
|
17
17
|
import { refreshOpenAICodex } from "./oauth/openai-codex.js";
|
|
@@ -169,18 +169,23 @@ export class ProviderRegistry {
|
|
|
169
169
|
continue;
|
|
170
170
|
if (!entry.result || !Array.isArray(entry.result.models))
|
|
171
171
|
continue;
|
|
172
|
+
const provider = { id: entry.providerId ?? "", authType: entry.authType, protocol: entry.protocol };
|
|
173
|
+
// Capability fields may have been derived by an older Bubble build.
|
|
174
|
+
// Recompute them with the current code while retaining cached remote
|
|
175
|
+
// membership, display names and context windows.
|
|
176
|
+
const result = normalizeProviderDiscoveryMetadata(provider, entry.result);
|
|
172
177
|
this.modelDiscoveryCache.set(key, {
|
|
173
|
-
result
|
|
178
|
+
result,
|
|
174
179
|
expiresAt: entry.expiresAt,
|
|
175
180
|
identityKey: entry.identityKey ?? "unknown",
|
|
176
|
-
providerId:
|
|
181
|
+
providerId: provider.id,
|
|
177
182
|
authType: entry.authType,
|
|
178
183
|
protocol: entry.protocol,
|
|
179
184
|
});
|
|
180
185
|
// Rebuild the dynamic overlay so context window / reasoning levels
|
|
181
186
|
// resolve from the cached catalog at startup, not only on /model open.
|
|
182
187
|
if (entry.providerId) {
|
|
183
|
-
this.applyDynamicDiscoveryMetadata(
|
|
188
|
+
this.applyDynamicDiscoveryMetadata(provider, result);
|
|
184
189
|
}
|
|
185
190
|
}
|
|
186
191
|
}
|
|
@@ -513,6 +518,8 @@ export class ProviderRegistry {
|
|
|
513
518
|
if (!options.forceRefresh) {
|
|
514
519
|
const cached = this.modelDiscoveryCache.get(key);
|
|
515
520
|
if (cached && cached.expiresAt > now) {
|
|
521
|
+
const cachedResult = normalizeProviderDiscoveryMetadata(provider, cached.result);
|
|
522
|
+
cached.result = cachedResult;
|
|
516
523
|
// A disk cache can outlive the application version that wrote it. Keep
|
|
517
524
|
// the current curated catalog authoritative over stale cached metadata,
|
|
518
525
|
// then retain cached remote-only ids for non-authoritative union results.
|
|
@@ -520,12 +527,12 @@ export class ProviderRegistry {
|
|
|
520
527
|
// without waiting up to 24 hours or requiring a manual Ctrl+R refresh.
|
|
521
528
|
const local = this.localModelsForProvider(provider);
|
|
522
529
|
const localIds = new Set(local.map((model) => model.id));
|
|
523
|
-
const models =
|
|
530
|
+
const models = cachedResult.source === "static"
|
|
524
531
|
? local
|
|
525
|
-
:
|
|
526
|
-
?
|
|
527
|
-
: [...local, ...
|
|
528
|
-
const result = { ...
|
|
532
|
+
: cachedResult.authoritative
|
|
533
|
+
? cachedResult.models
|
|
534
|
+
: [...local, ...cachedResult.models.filter((model) => !localIds.has(model.id))];
|
|
535
|
+
const result = { ...cachedResult, models, source: "cache" };
|
|
529
536
|
const current = this.getConfigured().find((item) => item.id === provider.id);
|
|
530
537
|
if (!current || this.modelDiscoveryKey(current) === key) {
|
|
531
538
|
this.applyDynamicDiscoveryMetadata(provider, result);
|
|
@@ -544,7 +551,8 @@ export class ProviderRegistry {
|
|
|
544
551
|
const generation = (this.modelDiscoveryGeneration.get(provider.id) ?? 0) + 1;
|
|
545
552
|
this.modelDiscoveryGeneration.set(provider.id, generation);
|
|
546
553
|
let pending;
|
|
547
|
-
pending = this.performModelDiscovery(provider).then((
|
|
554
|
+
pending = this.performModelDiscovery(provider).then((rawResult) => {
|
|
555
|
+
const result = normalizeProviderDiscoveryMetadata(provider, rawResult);
|
|
548
556
|
if (!this.isCurrentModelDiscovery(provider, key, generation)) {
|
|
549
557
|
return {
|
|
550
558
|
models: this.localModelsForProvider(this.getConfigured().find((item) => item.id === provider.id) ?? provider),
|
|
@@ -879,6 +887,22 @@ export class ProviderRegistry {
|
|
|
879
887
|
})));
|
|
880
888
|
}
|
|
881
889
|
}
|
|
890
|
+
/**
|
|
891
|
+
* Remote Gemini discovery does not expose Bubble's reasoning ladder; that
|
|
892
|
+
* metadata is inferred locally. Never trust a persisted inference across app
|
|
893
|
+
* upgrades, or a corrected capability matrix can remain stale for the cache
|
|
894
|
+
* TTL after restart.
|
|
895
|
+
*/
|
|
896
|
+
function normalizeProviderDiscoveryMetadata(provider, result) {
|
|
897
|
+
if (provider.id !== "google" || provider.protocol !== "ai-sdk")
|
|
898
|
+
return result;
|
|
899
|
+
return {
|
|
900
|
+
...result,
|
|
901
|
+
models: result.models.map((model) => model.id.startsWith("gemini-")
|
|
902
|
+
? { ...model, reasoningLevels: geminiReasoningLevels(model.id) }
|
|
903
|
+
: model),
|
|
904
|
+
};
|
|
905
|
+
}
|
|
882
906
|
function modelDiscoveryError(error) {
|
|
883
907
|
if (error instanceof Error && error.message.trim())
|
|
884
908
|
return error.message;
|
package/dist/sdk/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ import type { ResolvedSubagentRoute } from "../agent/categories.js";
|
|
|
21
21
|
import { type QuestionAnswer, type QuestionRequest } from "../question/controller.js";
|
|
22
22
|
import { SkillRegistry } from "../skills/registry.js";
|
|
23
23
|
import type { SkillSummary } from "../skills/types.js";
|
|
24
|
-
import type { AgentEvent, ContentPart, Message, PermissionMode, Provider, ThinkingLevel } from "../types.js";
|
|
24
|
+
import type { AgentEvent, AgentRunInput, ContentPart, Message, PermissionMode, Provider, ThinkingLevel } from "../types.js";
|
|
25
25
|
export interface BubbleSdkOptions {
|
|
26
26
|
/** Fallback working directory for sessions created without an explicit cwd. */
|
|
27
27
|
defaultCwd?: string;
|
|
@@ -81,6 +81,62 @@ export interface SdkSessionRef {
|
|
|
81
81
|
id: string;
|
|
82
82
|
cwd: string;
|
|
83
83
|
}
|
|
84
|
+
export interface SdkSessionRunState {
|
|
85
|
+
/** A turn owns the session slot, including setup and teardown. */
|
|
86
|
+
active: boolean;
|
|
87
|
+
queuedTurns: number;
|
|
88
|
+
pendingSteers: number;
|
|
89
|
+
phase: "idle" | "reserved" | "starting" | "active" | "stopping" | "deleted";
|
|
90
|
+
}
|
|
91
|
+
export type SdkSteerOutcome = Extract<AgentEvent, {
|
|
92
|
+
type: "input_applied" | "input_queued" | "input_rejected";
|
|
93
|
+
}>;
|
|
94
|
+
export type SdkSteerResult = {
|
|
95
|
+
accepted: true;
|
|
96
|
+
disposition: "steered";
|
|
97
|
+
input: AgentRunInput;
|
|
98
|
+
outcome: Promise<SdkSteerOutcome>;
|
|
99
|
+
} | {
|
|
100
|
+
accepted: true;
|
|
101
|
+
disposition: "queued";
|
|
102
|
+
input: AgentRunInput;
|
|
103
|
+
turnId: string;
|
|
104
|
+
outcome: Promise<SdkSteerOutcome>;
|
|
105
|
+
} | {
|
|
106
|
+
accepted: false;
|
|
107
|
+
disposition: "rejected";
|
|
108
|
+
reason: "unknown_session" | "session_deleted" | "ownership_conflict";
|
|
109
|
+
};
|
|
110
|
+
export interface SdkSessionEvent {
|
|
111
|
+
sequence: number;
|
|
112
|
+
sessionId: string;
|
|
113
|
+
turnId: string;
|
|
114
|
+
event: AgentEvent;
|
|
115
|
+
/**
|
|
116
|
+
* Present only on the synthesized record that ends a turn abnormally.
|
|
117
|
+
* Replay subscribers use it to tell "turn failed" from "turn still running";
|
|
118
|
+
* the per-turn runTurn() iterator instead surfaces the thrown error.
|
|
119
|
+
*/
|
|
120
|
+
terminal?: SdkSessionTerminal;
|
|
121
|
+
}
|
|
122
|
+
export interface SdkSessionTerminal {
|
|
123
|
+
kind: "failed" | "cancelled";
|
|
124
|
+
message: string;
|
|
125
|
+
}
|
|
126
|
+
export interface SdkStopOptions {
|
|
127
|
+
/** Match Claude-style interruption: queued messages survive by default. */
|
|
128
|
+
cancelQueued?: boolean;
|
|
129
|
+
}
|
|
130
|
+
export interface SdkSessionHandle extends SdkSessionRef {
|
|
131
|
+
/** Events from every turn in this session. Opening another handle reconnects from sequence 1. */
|
|
132
|
+
readonly events: AsyncIterable<SdkSessionEvent>;
|
|
133
|
+
/** Reconnect after the last sequence the host durably processed. */
|
|
134
|
+
eventsFrom(afterSequence: number): AsyncIterable<SdkSessionEvent>;
|
|
135
|
+
send(options: RunTurnOptions): AsyncGenerator<AgentEvent>;
|
|
136
|
+
steer(content: string): SdkSteerResult;
|
|
137
|
+
stop(options?: SdkStopOptions): number;
|
|
138
|
+
close(): void;
|
|
139
|
+
}
|
|
84
140
|
export declare class BubbleSdk {
|
|
85
141
|
readonly userConfig: UserConfig;
|
|
86
142
|
readonly registry: ProviderRegistry;
|
|
@@ -88,8 +144,13 @@ export declare class BubbleSdk {
|
|
|
88
144
|
private readonly mcpEnabled;
|
|
89
145
|
private readonly cwdBySession;
|
|
90
146
|
private readonly bashAllowlists;
|
|
91
|
-
private readonly
|
|
147
|
+
private readonly turnCoordinator;
|
|
148
|
+
private readonly turnRuntimes;
|
|
149
|
+
private readonly lastTurnOptions;
|
|
92
150
|
private readonly mcpToolsByCwd;
|
|
151
|
+
private readonly inputIdNonce;
|
|
152
|
+
private nextTurnInputPrefix;
|
|
153
|
+
private nextDetachedInputId;
|
|
93
154
|
/** id -> {cwd,file} rebuilt from disk so sessions survive host restarts. */
|
|
94
155
|
private sessionIndex;
|
|
95
156
|
constructor(options?: BubbleSdkOptions);
|
|
@@ -98,10 +159,21 @@ export declare class BubbleSdk {
|
|
|
98
159
|
cwd?: string;
|
|
99
160
|
id?: string;
|
|
100
161
|
}): SdkSessionRef;
|
|
162
|
+
openSession(sessionId: string): SdkSessionHandle;
|
|
101
163
|
getHistory(sessionId: string): Message[];
|
|
102
|
-
deleteSession(sessionId: string): void
|
|
103
|
-
/**
|
|
104
|
-
stop(sessionId: string):
|
|
164
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
165
|
+
/** Interrupt the active turn. Queued turns survive unless cancelQueued is true. */
|
|
166
|
+
stop(sessionId: string, options?: SdkStopOptions): number;
|
|
167
|
+
/** Cancel queued turns without interrupting the turn that owns the session slot. */
|
|
168
|
+
clearQueue(sessionId: string): number;
|
|
169
|
+
getSessionRunState(sessionId: string): SdkSessionRunState;
|
|
170
|
+
/**
|
|
171
|
+
* Add text to the turn that currently owns the session slot. Every accepted
|
|
172
|
+
* input exposes an outcome promise, independent of event-stream consumption.
|
|
173
|
+
*/
|
|
174
|
+
steer(sessionId: string, content: string): SdkSteerResult;
|
|
175
|
+
enqueueTurn(sessionId: string, options: RunTurnOptions): AsyncGenerator<AgentEvent>;
|
|
176
|
+
queueTurn(sessionId: string, options: RunTurnOptions): AsyncGenerator<AgentEvent>;
|
|
105
177
|
listSkills(cwd?: string): SkillSummary[];
|
|
106
178
|
/** Configured providers + default model, for a host's model picker. */
|
|
107
179
|
getModelConfig(): {
|
|
@@ -113,7 +185,25 @@ export declare class BubbleSdk {
|
|
|
113
185
|
hasApiKey: boolean;
|
|
114
186
|
}>;
|
|
115
187
|
};
|
|
188
|
+
/**
|
|
189
|
+
* Reserve and start a session turn immediately. Execution is driven by the
|
|
190
|
+
* SDK's own pump, not by consumption of the returned iterator: the iterator
|
|
191
|
+
* is a replay subscription, so a host may drop it (or reconnect later via
|
|
192
|
+
* `openSession`) without stalling or cancelling the turn. Cancel with
|
|
193
|
+
* `stop()`, the options signal, or `deleteSession()`.
|
|
194
|
+
*/
|
|
116
195
|
runTurn(sessionId: string, options: RunTurnOptions): AsyncGenerator<AgentEvent>;
|
|
196
|
+
private startOwnedTurn;
|
|
197
|
+
private pumpTurn;
|
|
198
|
+
private runReservedTurn;
|
|
199
|
+
private runtimesForSession;
|
|
200
|
+
private settleSteerFromEvent;
|
|
201
|
+
private handleSteerEvent;
|
|
202
|
+
private rejectOutstandingSteers;
|
|
203
|
+
private queuePendingSteer;
|
|
204
|
+
private queueDetachedInput;
|
|
205
|
+
private publishSessionEvent;
|
|
206
|
+
private ownerForSession;
|
|
117
207
|
private bashAllowlistFor;
|
|
118
208
|
/**
|
|
119
209
|
* Default cross-provider subagent factory over this SDK instance's own
|
|
@@ -141,6 +231,7 @@ export declare function attachTurnCost(event: AgentEvent, providerId: string, mo
|
|
|
141
231
|
*/
|
|
142
232
|
export declare function rewriteSkillInvocationPrompt(prompt: string | ContentPart[], registry: SkillRegistry): string | ContentPart[];
|
|
143
233
|
export { Agent, AgentAbortError, type AgentOptions, type AgentRunOptions } from "../agent.js";
|
|
234
|
+
export { AgentRunInputQueue } from "../agent/input-controller.js";
|
|
144
235
|
export { SessionManager, getSessionsDir, type SessionSummary, type UserTurn, type RewindResult, } from "../session.js";
|
|
145
236
|
export { PermissionAwareApprovalController } from "../approval/controller.js";
|
|
146
237
|
export { BashAllowlist } from "../approval/session-cache.js";
|
|
@@ -164,4 +255,4 @@ export { ExternalHookController } from "../hooks/controller.js";
|
|
|
164
255
|
export { calculateUsageCost, getModelPricing, type ModelPricing, type PricingCurrency, } from "../model-pricing.js";
|
|
165
256
|
export { registry as slashCommandRegistry } from "../slash-commands/index.js";
|
|
166
257
|
export type { SlashCommandContext } from "../slash-commands/types.js";
|
|
167
|
-
export type { AgentEvent, ContentPart, Message, PermissionMode, Provider, ThinkingLevel, TokenUsage, UsageCost, ToolRegistryEntry, ToolResult, ToolUpdate, } from "../types.js";
|
|
258
|
+
export type { AgentEvent, AgentInputController, AgentRunInput, ContentPart, Message, PermissionMode, Provider, ThinkingLevel, TokenUsage, UsageCost, ToolRegistryEntry, ToolResult, ToolUpdate, } from "../types.js";
|