@uncensoredcode/openbridge 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.
Files changed (145) hide show
  1. package/README.md +117 -0
  2. package/bin/openbridge.js +10 -0
  3. package/package.json +85 -0
  4. package/packages/cli/dist/args.d.ts +30 -0
  5. package/packages/cli/dist/args.js +160 -0
  6. package/packages/cli/dist/cli.d.ts +2 -0
  7. package/packages/cli/dist/cli.js +9 -0
  8. package/packages/cli/dist/index.d.ts +26 -0
  9. package/packages/cli/dist/index.js +76 -0
  10. package/packages/runtime/dist/assistant-protocol.d.ts +34 -0
  11. package/packages/runtime/dist/assistant-protocol.js +121 -0
  12. package/packages/runtime/dist/execution/in-process.d.ts +14 -0
  13. package/packages/runtime/dist/execution/in-process.js +45 -0
  14. package/packages/runtime/dist/execution/types.d.ts +49 -0
  15. package/packages/runtime/dist/execution/types.js +20 -0
  16. package/packages/runtime/dist/index.d.ts +86 -0
  17. package/packages/runtime/dist/index.js +60 -0
  18. package/packages/runtime/dist/normalizers/index.d.ts +6 -0
  19. package/packages/runtime/dist/normalizers/index.js +12 -0
  20. package/packages/runtime/dist/normalizers/legacy-packet.d.ts +6 -0
  21. package/packages/runtime/dist/normalizers/legacy-packet.js +131 -0
  22. package/packages/runtime/dist/output-sanitizer.d.ts +23 -0
  23. package/packages/runtime/dist/output-sanitizer.js +78 -0
  24. package/packages/runtime/dist/packet-extractor.d.ts +17 -0
  25. package/packages/runtime/dist/packet-extractor.js +43 -0
  26. package/packages/runtime/dist/packet-normalizer.d.ts +21 -0
  27. package/packages/runtime/dist/packet-normalizer.js +47 -0
  28. package/packages/runtime/dist/prompt-compiler.d.ts +28 -0
  29. package/packages/runtime/dist/prompt-compiler.js +301 -0
  30. package/packages/runtime/dist/protocol.d.ts +44 -0
  31. package/packages/runtime/dist/protocol.js +165 -0
  32. package/packages/runtime/dist/provider-failure.d.ts +52 -0
  33. package/packages/runtime/dist/provider-failure.js +236 -0
  34. package/packages/runtime/dist/provider.d.ts +40 -0
  35. package/packages/runtime/dist/provider.js +1 -0
  36. package/packages/runtime/dist/runtime.d.ts +86 -0
  37. package/packages/runtime/dist/runtime.js +462 -0
  38. package/packages/runtime/dist/session-bound-provider.d.ts +52 -0
  39. package/packages/runtime/dist/session-bound-provider.js +366 -0
  40. package/packages/runtime/dist/tool-name-aliases.d.ts +5 -0
  41. package/packages/runtime/dist/tool-name-aliases.js +13 -0
  42. package/packages/runtime/dist/tools/bash.d.ts +9 -0
  43. package/packages/runtime/dist/tools/bash.js +157 -0
  44. package/packages/runtime/dist/tools/edit.d.ts +9 -0
  45. package/packages/runtime/dist/tools/edit.js +94 -0
  46. package/packages/runtime/dist/tools/index.d.ts +39 -0
  47. package/packages/runtime/dist/tools/index.js +27 -0
  48. package/packages/runtime/dist/tools/list-dir.d.ts +9 -0
  49. package/packages/runtime/dist/tools/list-dir.js +127 -0
  50. package/packages/runtime/dist/tools/read.d.ts +9 -0
  51. package/packages/runtime/dist/tools/read.js +56 -0
  52. package/packages/runtime/dist/tools/registry.d.ts +15 -0
  53. package/packages/runtime/dist/tools/registry.js +38 -0
  54. package/packages/runtime/dist/tools/runtime-path.d.ts +7 -0
  55. package/packages/runtime/dist/tools/runtime-path.js +22 -0
  56. package/packages/runtime/dist/tools/search-files.d.ts +9 -0
  57. package/packages/runtime/dist/tools/search-files.js +149 -0
  58. package/packages/runtime/dist/tools/text-file.d.ts +32 -0
  59. package/packages/runtime/dist/tools/text-file.js +101 -0
  60. package/packages/runtime/dist/tools/workspace-path.d.ts +17 -0
  61. package/packages/runtime/dist/tools/workspace-path.js +70 -0
  62. package/packages/runtime/dist/tools/write.d.ts +9 -0
  63. package/packages/runtime/dist/tools/write.js +59 -0
  64. package/packages/server/dist/bridge/bridge-model-catalog.d.ts +56 -0
  65. package/packages/server/dist/bridge/bridge-model-catalog.js +100 -0
  66. package/packages/server/dist/bridge/bridge-runtime-service.d.ts +61 -0
  67. package/packages/server/dist/bridge/bridge-runtime-service.js +1386 -0
  68. package/packages/server/dist/bridge/chat-completions/chat-completion-service.d.ts +127 -0
  69. package/packages/server/dist/bridge/chat-completions/chat-completion-service.js +1026 -0
  70. package/packages/server/dist/bridge/index.d.ts +335 -0
  71. package/packages/server/dist/bridge/index.js +45 -0
  72. package/packages/server/dist/bridge/live-provider-extraction-canary.d.ts +69 -0
  73. package/packages/server/dist/bridge/live-provider-extraction-canary.js +186 -0
  74. package/packages/server/dist/bridge/providers/generic-provider-transport.d.ts +53 -0
  75. package/packages/server/dist/bridge/providers/generic-provider-transport.js +973 -0
  76. package/packages/server/dist/bridge/providers/provider-session-resolver.d.ts +17 -0
  77. package/packages/server/dist/bridge/providers/provider-session-resolver.js +95 -0
  78. package/packages/server/dist/bridge/providers/provider-streams.d.ts +80 -0
  79. package/packages/server/dist/bridge/providers/provider-streams.js +844 -0
  80. package/packages/server/dist/bridge/providers/provider-transport-profile.d.ts +194 -0
  81. package/packages/server/dist/bridge/providers/provider-transport-profile.js +198 -0
  82. package/packages/server/dist/bridge/providers/web-provider-transport.d.ts +30 -0
  83. package/packages/server/dist/bridge/providers/web-provider-transport.js +151 -0
  84. package/packages/server/dist/bridge/state/file-bridge-state-store.d.ts +36 -0
  85. package/packages/server/dist/bridge/state/file-bridge-state-store.js +164 -0
  86. package/packages/server/dist/bridge/stores/local-session-package-store.d.ts +23 -0
  87. package/packages/server/dist/bridge/stores/local-session-package-store.js +548 -0
  88. package/packages/server/dist/bridge/stores/provider-store.d.ts +94 -0
  89. package/packages/server/dist/bridge/stores/provider-store.js +143 -0
  90. package/packages/server/dist/bridge/stores/session-backed-provider-store.d.ts +7 -0
  91. package/packages/server/dist/bridge/stores/session-backed-provider-store.js +26 -0
  92. package/packages/server/dist/bridge/stores/session-package-store.d.ts +286 -0
  93. package/packages/server/dist/bridge/stores/session-package-store.js +1527 -0
  94. package/packages/server/dist/bridge/stores/session-store.d.ts +120 -0
  95. package/packages/server/dist/bridge/stores/session-store.js +139 -0
  96. package/packages/server/dist/cli/index.d.ts +9 -0
  97. package/packages/server/dist/cli/index.js +6 -0
  98. package/packages/server/dist/cli/main.d.ts +2 -0
  99. package/packages/server/dist/cli/main.js +9 -0
  100. package/packages/server/dist/cli/run-bridge-server-cli.d.ts +54 -0
  101. package/packages/server/dist/cli/run-bridge-server-cli.js +371 -0
  102. package/packages/server/dist/client/bridge-api-client.d.ts +61 -0
  103. package/packages/server/dist/client/bridge-api-client.js +267 -0
  104. package/packages/server/dist/client/index.d.ts +11 -0
  105. package/packages/server/dist/client/index.js +11 -0
  106. package/packages/server/dist/config/bridge-server-config.d.ts +52 -0
  107. package/packages/server/dist/config/bridge-server-config.js +118 -0
  108. package/packages/server/dist/config/index.d.ts +20 -0
  109. package/packages/server/dist/config/index.js +8 -0
  110. package/packages/server/dist/http/bridge-api-route-context.d.ts +14 -0
  111. package/packages/server/dist/http/bridge-api-route-context.js +1 -0
  112. package/packages/server/dist/http/create-bridge-api-server.d.ts +72 -0
  113. package/packages/server/dist/http/create-bridge-api-server.js +225 -0
  114. package/packages/server/dist/http/index.d.ts +5 -0
  115. package/packages/server/dist/http/index.js +5 -0
  116. package/packages/server/dist/http/parse-request.d.ts +6 -0
  117. package/packages/server/dist/http/parse-request.js +27 -0
  118. package/packages/server/dist/http/register-bridge-api-routes.d.ts +7 -0
  119. package/packages/server/dist/http/register-bridge-api-routes.js +17 -0
  120. package/packages/server/dist/http/routes/admin-routes.d.ts +7 -0
  121. package/packages/server/dist/http/routes/admin-routes.js +135 -0
  122. package/packages/server/dist/http/routes/chat-completions-route.d.ts +7 -0
  123. package/packages/server/dist/http/routes/chat-completions-route.js +49 -0
  124. package/packages/server/dist/http/routes/health-routes.d.ts +6 -0
  125. package/packages/server/dist/http/routes/health-routes.js +7 -0
  126. package/packages/server/dist/http/routes/message-routes.d.ts +7 -0
  127. package/packages/server/dist/http/routes/message-routes.js +7 -0
  128. package/packages/server/dist/index.d.ts +85 -0
  129. package/packages/server/dist/index.js +28 -0
  130. package/packages/server/dist/security/bridge-auth.d.ts +9 -0
  131. package/packages/server/dist/security/bridge-auth.js +41 -0
  132. package/packages/server/dist/security/cors-policy.d.ts +5 -0
  133. package/packages/server/dist/security/cors-policy.js +34 -0
  134. package/packages/server/dist/security/index.d.ts +16 -0
  135. package/packages/server/dist/security/index.js +12 -0
  136. package/packages/server/dist/security/redact-sensitive-values.d.ts +19 -0
  137. package/packages/server/dist/security/redact-sensitive-values.js +67 -0
  138. package/packages/server/dist/shared/api-schema.d.ts +133 -0
  139. package/packages/server/dist/shared/api-schema.js +1 -0
  140. package/packages/server/dist/shared/bridge-api-error.d.ts +17 -0
  141. package/packages/server/dist/shared/bridge-api-error.js +19 -0
  142. package/packages/server/dist/shared/index.d.ts +7 -0
  143. package/packages/server/dist/shared/index.js +7 -0
  144. package/packages/server/dist/shared/output.d.ts +5 -0
  145. package/packages/server/dist/shared/output.js +14 -0
@@ -0,0 +1,462 @@
1
+ import { assistantProtocolModule } from "./assistant-protocol.js";
2
+ import { packetExtractorModule } from "./packet-extractor.js";
3
+ import { packetNormalizerModule } from "./packet-normalizer.js";
4
+ import { protocolModule } from "./protocol.js";
5
+ import { providerFailureModule } from "./provider-failure.js";
6
+ import { toolNameAliasesModule } from "./tool-name-aliases.js";
7
+ const { parseAssistantResponse, validateAssistantResponse } = assistantProtocolModule;
8
+ const { extractPacketCandidate } = packetExtractorModule;
9
+ const { normalizeProviderPacket } = packetNormalizerModule;
10
+ const { parseZcPacket, serializeToolResult } = protocolModule;
11
+ const { normalizeProviderToolName } = toolNameAliasesModule;
12
+ const { formatProviderFailureMessage, isProviderFailure, serializeProviderFailure, withProviderRecovery } = providerFailureModule;
13
+ const DEFAULT_MAX_STEPS = 8;
14
+ async function runBridgeRuntime(input) {
15
+ const maxSteps = input.config?.maxSteps ?? DEFAULT_MAX_STEPS;
16
+ const conversation = {
17
+ sessionHistory: input.sessionHistory ?? [],
18
+ entries: [
19
+ {
20
+ type: "user_message",
21
+ content: input.userMessage
22
+ }
23
+ ]
24
+ };
25
+ const availableTools = await input.toolExecutor.getAvailableTools();
26
+ for (let step = 1; step <= maxSteps; step += 1) {
27
+ let rawText;
28
+ const providerStartedAt = Date.now();
29
+ try {
30
+ rawText = await input.provider.completeTurn({
31
+ conversation,
32
+ availableTools
33
+ });
34
+ }
35
+ catch (error) {
36
+ if (isProviderFailure(error)) {
37
+ const serialized = serializeProviderFailure(withProviderRecovery(error, error.recovery, {
38
+ displayMessage: formatProviderFailureMessage(error)
39
+ }));
40
+ return emitOutcome({
41
+ mode: "fail",
42
+ message: serialized.message,
43
+ steps: step,
44
+ conversation,
45
+ failure: {
46
+ source: "provider",
47
+ provider: serialized
48
+ }
49
+ }, input.config);
50
+ }
51
+ return emitOutcome({
52
+ mode: "fail",
53
+ message: `Provider adapter failed: ${error instanceof Error ? error.message : String(error)}`,
54
+ steps: step,
55
+ conversation,
56
+ failure: {
57
+ source: "provider",
58
+ provider: {
59
+ kind: "permanent",
60
+ code: "transport_error",
61
+ message: `Provider adapter failed: ${error instanceof Error ? error.message : String(error)}`,
62
+ retryable: false,
63
+ sessionResetEligible: false,
64
+ emptyOutput: false,
65
+ recovery: {
66
+ softRetryCount: 0,
67
+ sessionResetCount: 0
68
+ }
69
+ }
70
+ }
71
+ }, input.config);
72
+ }
73
+ input.config?.onEvent?.({
74
+ type: "provider_response",
75
+ step,
76
+ rawText,
77
+ durationMs: Date.now() - providerStartedAt
78
+ });
79
+ let response;
80
+ try {
81
+ response = parseAndValidateProviderResponse(input.provider.id, rawText, availableTools);
82
+ }
83
+ catch (error) {
84
+ const validationError = error instanceof Error ? error.message : String(error);
85
+ input.config?.onEvent?.({
86
+ type: "main_response_invalid",
87
+ step,
88
+ error: validationError,
89
+ rawTextLength: rawText.length
90
+ });
91
+ input.config?.onEvent?.({
92
+ type: "packet_parse_failed",
93
+ step,
94
+ error: validationError
95
+ });
96
+ input.config?.onEvent?.({
97
+ type: "repair_attempted",
98
+ step
99
+ });
100
+ const repaired = await attemptResponseRepair({
101
+ provider: input.provider,
102
+ conversation,
103
+ availableTools,
104
+ invalidResponse: rawText,
105
+ validationError
106
+ });
107
+ if (!repaired.ok) {
108
+ input.config?.onEvent?.({
109
+ type: "repair_failed",
110
+ step,
111
+ reason: repaired.failure.source === "provider" ? "provider_failure" : "protocol_invalid",
112
+ error: repaired.failure.source === "protocol" ? repaired.failure.message : undefined,
113
+ providerFailure: repaired.failure.source === "provider"
114
+ ? {
115
+ kind: repaired.failure.provider.kind,
116
+ code: repaired.failure.provider.code,
117
+ message: repaired.failure.provider.message
118
+ }
119
+ : undefined
120
+ });
121
+ if (repaired.failure.source === "provider") {
122
+ return emitOutcome({
123
+ mode: "fail",
124
+ message: repaired.failure.provider.message,
125
+ steps: step,
126
+ conversation,
127
+ failure: repaired.failure
128
+ }, input.config);
129
+ }
130
+ return emitOutcome({
131
+ mode: "fail",
132
+ message: repaired.failure.message,
133
+ steps: step,
134
+ conversation,
135
+ failure: repaired.failure
136
+ }, input.config);
137
+ }
138
+ rawText = repaired.rawText;
139
+ try {
140
+ response = parseAndValidateProviderResponse(input.provider.id, rawText, availableTools);
141
+ }
142
+ catch (repairError) {
143
+ const repairValidationError = repairError instanceof Error ? repairError.message : String(repairError);
144
+ input.config?.onEvent?.({
145
+ type: "packet_parse_failed",
146
+ step,
147
+ error: repairValidationError
148
+ });
149
+ input.config?.onEvent?.({
150
+ type: "repair_failed",
151
+ step,
152
+ reason: "protocol_invalid",
153
+ error: `Invalid assistant response: ${repairValidationError}`
154
+ });
155
+ return emitOutcome({
156
+ mode: "fail",
157
+ message: `Invalid assistant response: ${repairValidationError}`,
158
+ steps: step,
159
+ conversation,
160
+ failure: {
161
+ source: "protocol",
162
+ code: "malformed_provider_packet",
163
+ message: `Invalid assistant response: ${repairValidationError}`
164
+ }
165
+ }, input.config);
166
+ }
167
+ input.config?.onEvent?.({
168
+ type: "repair_valid",
169
+ step,
170
+ mode: getParsedResponseMode(response),
171
+ rawTextLength: rawText.length
172
+ });
173
+ }
174
+ input.config?.onEvent?.({
175
+ type: "packet_parsed",
176
+ step,
177
+ mode: getParsedResponseMode(response)
178
+ });
179
+ conversation.entries.push({
180
+ type: "provider_packet",
181
+ rawText,
182
+ packet: response
183
+ });
184
+ if (isAssistantToolResponse(response) || isZcToolRequest(response)) {
185
+ const toolCall = isZcToolRequest(response)
186
+ ? {
187
+ id: response.toolCall.id,
188
+ name: response.toolCall.name,
189
+ args: response.toolCall.args
190
+ }
191
+ : {
192
+ id: `call_${step}`,
193
+ name: response.toolCall.name,
194
+ args: response.toolCall.arguments
195
+ };
196
+ const toolStartedAt = Date.now();
197
+ const execution = await input.toolExecutor.executeTool({
198
+ call: toolCall
199
+ });
200
+ const toolResult = {
201
+ id: toolCall.id,
202
+ name: toolCall.name,
203
+ ok: execution.ok,
204
+ payload: execution.payload
205
+ };
206
+ const serializedToolResult = serializeToolResult(toolResult);
207
+ conversation.entries.push({
208
+ type: "tool_result",
209
+ rawText: serializedToolResult,
210
+ result: toolResult
211
+ });
212
+ input.config?.onEvent?.({
213
+ type: "tool_result",
214
+ step,
215
+ rawText: serializedToolResult,
216
+ result: toolResult,
217
+ durationMs: Date.now() - toolStartedAt
218
+ });
219
+ continue;
220
+ }
221
+ switch (getParsedResponseMode(response)) {
222
+ case "final":
223
+ return emitOutcome({
224
+ mode: "final",
225
+ message: extractParsedResponseMessage(response),
226
+ steps: step,
227
+ conversation
228
+ }, input.config);
229
+ case "ask_user":
230
+ return emitOutcome({
231
+ mode: "ask_user",
232
+ message: extractParsedResponseMessage(response),
233
+ steps: step,
234
+ conversation
235
+ }, input.config);
236
+ case "fail":
237
+ return emitOutcome({
238
+ mode: "fail",
239
+ message: extractParsedResponseMessage(response),
240
+ steps: step,
241
+ conversation
242
+ }, input.config);
243
+ }
244
+ }
245
+ return emitOutcome({
246
+ mode: "fail",
247
+ message: `Runtime exceeded max steps (${maxSteps}).`,
248
+ steps: maxSteps,
249
+ conversation,
250
+ failure: {
251
+ source: "runtime",
252
+ code: "max_steps_exhausted",
253
+ message: `Runtime exceeded max steps (${maxSteps}).`
254
+ }
255
+ }, input.config);
256
+ }
257
+ function repairLeadingAssistantBlock(content) {
258
+ const trimmed = content.trim();
259
+ const recovered = recoverLatestFinalBlock(trimmed);
260
+ if (recovered) {
261
+ return recovered;
262
+ }
263
+ return trimmed;
264
+ }
265
+ function recoverLatestFinalBlock(content) {
266
+ return recoverLatestTaggedBlock(content, "final")?.block ?? null;
267
+ }
268
+ function recoverLatestTaggedBlock(content, tag) {
269
+ const closeTag = `</${tag}>`;
270
+ const closeIndex = content.lastIndexOf(closeTag);
271
+ if (closeIndex < 0) {
272
+ return null;
273
+ }
274
+ const marker = new RegExp(`(?:<)?${tag}>`, "gi");
275
+ let latestMatch = null;
276
+ for (const match of content.matchAll(marker)) {
277
+ const index = match.index ?? -1;
278
+ if (index < 0 || index >= closeIndex) {
279
+ continue;
280
+ }
281
+ latestMatch = {
282
+ index,
283
+ markerLength: match[0].length
284
+ };
285
+ }
286
+ if (!latestMatch) {
287
+ return null;
288
+ }
289
+ const innerContent = content.slice(latestMatch.index + latestMatch.markerLength, closeIndex);
290
+ return {
291
+ index: latestMatch.index,
292
+ block: `<${tag}>${innerContent}${closeTag}`
293
+ };
294
+ }
295
+ function parseAndValidateProviderResponse(providerId, rawText, availableTools) {
296
+ const normalizedAssistantResponse = repairLeadingAssistantBlock(rawText);
297
+ try {
298
+ return validateAssistantResponse(normalizeAssistantToolNames(parseAssistantResponse(normalizedAssistantResponse)), availableTools);
299
+ }
300
+ catch (assistantError) {
301
+ const extraction = extractPacketCandidate(rawText);
302
+ if (!extraction.ok) {
303
+ throw assistantError;
304
+ }
305
+ const normalization = normalizeProviderPacket(providerId, extraction.packetText);
306
+ if (!normalization.ok) {
307
+ throw assistantError;
308
+ }
309
+ const packet = normalizeZcPacketToolNames(parseZcPacket(normalization.canonicalPacket));
310
+ validateZcPacketResponse(packet, availableTools);
311
+ return packet;
312
+ }
313
+ }
314
+ function normalizeAssistantToolNames(response) {
315
+ if (response.type !== "tool") {
316
+ return response;
317
+ }
318
+ return {
319
+ ...response,
320
+ toolCall: {
321
+ ...response.toolCall,
322
+ name: normalizeProviderToolName(response.toolCall.name)
323
+ }
324
+ };
325
+ }
326
+ function normalizeZcPacketToolNames(packet) {
327
+ if (packet.mode !== "tool_request") {
328
+ return packet;
329
+ }
330
+ return {
331
+ ...packet,
332
+ toolCall: {
333
+ ...packet.toolCall,
334
+ name: normalizeProviderToolName(packet.toolCall.name)
335
+ }
336
+ };
337
+ }
338
+ function validateZcPacketResponse(packet, availableTools) {
339
+ if (packet.mode !== "tool_request") {
340
+ return;
341
+ }
342
+ const tool = availableTools.find((candidate) => candidate.name === packet.toolCall.name);
343
+ if (!tool) {
344
+ return;
345
+ }
346
+ const argumentsRecord = packet.toolCall.args;
347
+ const propertyNames = Object.keys(tool.inputSchema.properties);
348
+ const allowedProperties = new Set(propertyNames);
349
+ for (const name of Object.keys(argumentsRecord)) {
350
+ if (!allowedProperties.has(name)) {
351
+ throw new Error(`Tool "${tool.name}" received unknown argument "${name}".`);
352
+ }
353
+ }
354
+ for (const requiredName of tool.inputSchema.required) {
355
+ if (!(requiredName in argumentsRecord)) {
356
+ throw new Error(`Tool "${tool.name}" is missing required argument "${requiredName}".`);
357
+ }
358
+ }
359
+ for (const propertyName of propertyNames) {
360
+ if (!(propertyName in argumentsRecord)) {
361
+ continue;
362
+ }
363
+ const property = tool.inputSchema.properties[propertyName];
364
+ const value = argumentsRecord[propertyName];
365
+ if (property.type === "string" && typeof value !== "string") {
366
+ throw new Error(`Tool "${tool.name}" argument "${propertyName}" must be a string.`);
367
+ }
368
+ if (property.type === "boolean" && typeof value !== "boolean") {
369
+ throw new Error(`Tool "${tool.name}" argument "${propertyName}" must be a boolean.`);
370
+ }
371
+ }
372
+ }
373
+ function isAssistantToolResponse(response) {
374
+ return "type" in response && response.type === "tool";
375
+ }
376
+ function isAssistantFinalResponse(response) {
377
+ return "type" in response && response.type === "final";
378
+ }
379
+ function isZcToolRequest(response) {
380
+ return "mode" in response && response.mode === "tool_request";
381
+ }
382
+ function getParsedResponseMode(response) {
383
+ if ("type" in response) {
384
+ return response.type;
385
+ }
386
+ return response.mode === "tool_request" ? "tool" : response.mode;
387
+ }
388
+ function extractParsedResponseMessage(response) {
389
+ if (isAssistantFinalResponse(response)) {
390
+ return response.message;
391
+ }
392
+ if (isAssistantToolResponse(response) || isZcToolRequest(response)) {
393
+ throw new Error("tool_request packets do not carry assistant text.");
394
+ }
395
+ return response.message;
396
+ }
397
+ function emitOutcome(outcome, config) {
398
+ config?.onEvent?.({
399
+ type: "outcome",
400
+ outcome
401
+ });
402
+ return outcome;
403
+ }
404
+ async function attemptResponseRepair(input) {
405
+ if (typeof input.provider.repairInvalidResponse !== "function") {
406
+ return {
407
+ ok: false,
408
+ failure: {
409
+ source: "protocol",
410
+ code: "malformed_provider_packet",
411
+ message: `Invalid assistant response: ${input.validationError}`
412
+ }
413
+ };
414
+ }
415
+ try {
416
+ const rawText = await input.provider.repairInvalidResponse({
417
+ conversation: input.conversation,
418
+ availableTools: input.availableTools,
419
+ invalidResponse: input.invalidResponse,
420
+ validationError: input.validationError
421
+ });
422
+ return {
423
+ ok: true,
424
+ rawText
425
+ };
426
+ }
427
+ catch (error) {
428
+ if (isProviderFailure(error)) {
429
+ const serialized = serializeProviderFailure(withProviderRecovery(error, error.recovery, {
430
+ displayMessage: formatProviderFailureMessage(error)
431
+ }));
432
+ return {
433
+ ok: false,
434
+ failure: {
435
+ source: "provider",
436
+ provider: serialized
437
+ }
438
+ };
439
+ }
440
+ return {
441
+ ok: false,
442
+ failure: {
443
+ source: "provider",
444
+ provider: {
445
+ kind: "permanent",
446
+ code: "transport_error",
447
+ message: `Provider repair adapter failed: ${error instanceof Error ? error.message : String(error)}`,
448
+ retryable: false,
449
+ sessionResetEligible: false,
450
+ emptyOutput: false,
451
+ recovery: {
452
+ softRetryCount: 0,
453
+ sessionResetCount: 0
454
+ }
455
+ }
456
+ }
457
+ };
458
+ }
459
+ }
460
+ export const runtimeModule = {
461
+ runBridgeRuntime
462
+ };
@@ -0,0 +1,52 @@
1
+ import type { CompiledProviderMessage } from "./prompt-compiler.ts";
2
+ import type { ProviderAdapter, ProviderTurnInput, RepairInvalidResponseInput } from "./provider.ts";
3
+ type UpstreamConversationBinding = {
4
+ conversationId: string;
5
+ parentId: string;
6
+ runtimePlannerPrimed?: boolean;
7
+ };
8
+ interface SessionBindingStore {
9
+ loadBinding(providerId: string, sessionId: string): Promise<UpstreamConversationBinding | null>;
10
+ saveBinding(providerId: string, sessionId: string, binding: UpstreamConversationBinding): Promise<void>;
11
+ clearBinding(providerId: string, sessionId: string): Promise<void>;
12
+ }
13
+ type ProviderTransportRequest = {
14
+ lane: "main" | "repair";
15
+ providerId: string;
16
+ modelId: string;
17
+ sessionId: string;
18
+ requestId: string;
19
+ attempt: number;
20
+ continuation: boolean;
21
+ toolFollowUp: boolean;
22
+ providerSessionReused: boolean;
23
+ messages: CompiledProviderMessage[];
24
+ upstreamBinding: Pick<UpstreamConversationBinding, "conversationId" | "parentId"> | null;
25
+ };
26
+ type ProviderTransportResponse = {
27
+ content: string;
28
+ upstreamBinding?: Pick<UpstreamConversationBinding, "conversationId" | "parentId"> | null;
29
+ };
30
+ interface ProviderTransport {
31
+ completeChat(request: ProviderTransportRequest): Promise<ProviderTransportResponse>;
32
+ }
33
+ type SessionBoundProviderAdapterOptions = {
34
+ providerId: string;
35
+ modelId: string;
36
+ transport: ProviderTransport;
37
+ sessionBindingStore?: SessionBindingStore;
38
+ sessionId?: string;
39
+ bridgeRequestId?: string;
40
+ onTraceEvent?: (type: string, detail: unknown) => void;
41
+ };
42
+ declare class SessionBoundProviderAdapter implements ProviderAdapter {
43
+ #private;
44
+ readonly id: string;
45
+ constructor(options: SessionBoundProviderAdapterOptions);
46
+ completeTurn(input: ProviderTurnInput): Promise<string>;
47
+ repairInvalidResponse(input: RepairInvalidResponseInput): Promise<string>;
48
+ }
49
+ export declare const sessionBoundProviderModule: {
50
+ SessionBoundProviderAdapter: typeof SessionBoundProviderAdapter;
51
+ };
52
+ export type { ProviderTransport, ProviderTransportRequest, ProviderTransportResponse, SessionBindingStore, SessionBoundProviderAdapter, SessionBoundProviderAdapterOptions, UpstreamConversationBinding };