@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,135 @@
1
+ import { bridgeModule } from "../../bridge/index.js";
2
+ import { bridgeApiErrorModule } from "../../shared/bridge-api-error.js";
3
+ import { parseRequestModule } from "../parse-request.js";
4
+ const { buildModelListResponse, createModelRequestSchema, buildSessionPackageStatus, createProviderRequestSchema, modelMutationResponseSchema, createSessionRequestSchema, providerDeleteResponseSchema, providerIdParamsSchema, providerListResponseSchema, providerResponseSchema, sessionDeleteResponseSchema, sessionIdParamsSchema, sessionListResponseSchema, sessionPackageDeleteResponseSchema, sessionPackageSchema, sessionPackageStatusResponseSchema, sessionResponseSchema, updateProviderRequestSchema, updateSessionRequestSchema } = bridgeModule;
5
+ const { BridgeApiError } = bridgeApiErrorModule;
6
+ const { parseRequest } = parseRequestModule;
7
+ function registerAdminRoutes(app, context) {
8
+ app.get("/v1/models", async () => buildModelListResponse(context.providerStore.list()));
9
+ app.post("/v1/models", async (request, reply) => {
10
+ const body = parseRequest(createModelRequestSchema, request.body);
11
+ const provider = requireProvider(context, body.provider);
12
+ const modelId = body.model.trim();
13
+ const currentModels = Array.isArray(provider.config.models)
14
+ ? provider.config.models.filter((value) => typeof value === "string")
15
+ : [];
16
+ const nextModels = [...new Set([...currentModels.map((value) => value.trim()), modelId])]
17
+ .filter(Boolean)
18
+ .sort((left, right) => left.localeCompare(right));
19
+ context.providerStore.update(provider.id, {
20
+ config: {
21
+ ...provider.config,
22
+ models: nextModels
23
+ }
24
+ });
25
+ reply.code(201);
26
+ return modelMutationResponseSchema.parse({
27
+ ok: true,
28
+ providerId: provider.id,
29
+ modelId
30
+ });
31
+ });
32
+ app.get("/v1/providers", async () => providerListResponseSchema.parse({
33
+ providers: context.providerStore.list()
34
+ }));
35
+ app.post("/v1/providers", async (request, reply) => {
36
+ const body = parseRequest(createProviderRequestSchema, request.body);
37
+ const provider = context.providerStore.create(body);
38
+ reply.code(201);
39
+ return providerResponseSchema.parse({ provider });
40
+ });
41
+ app.get("/v1/providers/:id", async (request) => {
42
+ const params = parseRequest(providerIdParamsSchema, request.params);
43
+ const provider = context.providerStore.get(params.id);
44
+ if (!provider) {
45
+ throw providerNotFoundError(params.id);
46
+ }
47
+ return providerResponseSchema.parse({ provider });
48
+ });
49
+ app.patch("/v1/providers/:id", async (request) => {
50
+ const params = parseRequest(providerIdParamsSchema, request.params);
51
+ const body = parseRequest(updateProviderRequestSchema, request.body);
52
+ const provider = context.providerStore.update(params.id, body);
53
+ return providerResponseSchema.parse({ provider });
54
+ });
55
+ app.delete("/v1/providers/:id", async (request) => {
56
+ const params = parseRequest(providerIdParamsSchema, request.params);
57
+ const deleted = context.providerStore.delete(params.id);
58
+ return providerDeleteResponseSchema.parse(deleted);
59
+ });
60
+ app.put("/v1/providers/:id/session-package", async (request) => {
61
+ const params = parseRequest(providerIdParamsSchema, request.params);
62
+ const body = parseRequest(sessionPackageSchema, request.body);
63
+ const stored = context.sessionPackageStore.put(params.id, body);
64
+ return sessionPackageStatusResponseSchema.parse(buildSessionPackageStatus(params.id, stored));
65
+ });
66
+ app.get("/v1/providers/:id/session-package", async (request) => {
67
+ const params = parseRequest(providerIdParamsSchema, request.params);
68
+ requireProvider(context, params.id);
69
+ const stored = context.sessionPackageStore.getStatus(params.id);
70
+ if (!stored || !stored.hasSessionPackage) {
71
+ throw new BridgeApiError({
72
+ statusCode: 404,
73
+ code: "session_package_not_found",
74
+ message: `Provider '${params.id}' does not have a session package.`
75
+ });
76
+ }
77
+ return sessionPackageStatusResponseSchema.parse(buildSessionPackageStatus(params.id, stored));
78
+ });
79
+ app.delete("/v1/providers/:id/session-package", async (request) => {
80
+ const params = parseRequest(providerIdParamsSchema, request.params);
81
+ requireProvider(context, params.id);
82
+ return sessionPackageDeleteResponseSchema.parse(context.sessionPackageStore.deleteSession(params.id));
83
+ });
84
+ app.get("/v1/sessions", async () => sessionListResponseSchema.parse({
85
+ sessions: context.sessionStore.list()
86
+ }));
87
+ app.post("/v1/sessions", async (request, reply) => {
88
+ const body = parseRequest(createSessionRequestSchema, request.body);
89
+ const session = context.sessionStore.create(body);
90
+ reply.code(201);
91
+ return sessionResponseSchema.parse({ session });
92
+ });
93
+ app.get("/v1/sessions/:id", async (request) => {
94
+ const params = parseRequest(sessionIdParamsSchema, request.params);
95
+ const session = context.sessionStore.get(params.id);
96
+ if (!session) {
97
+ throw sessionNotFoundError(params.id);
98
+ }
99
+ return sessionResponseSchema.parse({ session });
100
+ });
101
+ app.patch("/v1/sessions/:id", async (request) => {
102
+ const params = parseRequest(sessionIdParamsSchema, request.params);
103
+ const body = parseRequest(updateSessionRequestSchema, request.body);
104
+ const session = context.sessionStore.update(params.id, body);
105
+ return sessionResponseSchema.parse({ session });
106
+ });
107
+ app.delete("/v1/sessions/:id", async (request) => {
108
+ const params = parseRequest(sessionIdParamsSchema, request.params);
109
+ return sessionDeleteResponseSchema.parse(context.sessionStore.delete(params.id));
110
+ });
111
+ }
112
+ function requireProvider(context, providerId) {
113
+ const provider = context.providerStore.get(providerId);
114
+ if (provider) {
115
+ return provider;
116
+ }
117
+ throw providerNotFoundError(providerId);
118
+ }
119
+ function providerNotFoundError(providerId) {
120
+ return new BridgeApiError({
121
+ statusCode: 404,
122
+ code: "provider_not_found",
123
+ message: `Provider '${providerId}' was not found.`
124
+ });
125
+ }
126
+ function sessionNotFoundError(sessionId) {
127
+ return new BridgeApiError({
128
+ statusCode: 404,
129
+ code: "session_not_found",
130
+ message: `Session '${sessionId}' was not found.`
131
+ });
132
+ }
133
+ export const adminRoutesModule = {
134
+ registerAdminRoutes
135
+ };
@@ -0,0 +1,7 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import type { BridgeApiRouteContext } from "../bridge-api-route-context.ts";
3
+ declare function registerChatCompletionRoute(app: FastifyInstance, context: BridgeApiRouteContext): void;
4
+ export declare const chatCompletionsRouteModule: {
5
+ registerChatCompletionRoute: typeof registerChatCompletionRoute;
6
+ };
7
+ export {};
@@ -0,0 +1,49 @@
1
+ import { chatCompletionServiceModule } from "../../bridge/chat-completions/chat-completion-service.js";
2
+ import { fileBridgeStateStoreModule } from "../../bridge/state/file-bridge-state-store.js";
3
+ import { parseRequestModule } from "../parse-request.js";
4
+ const { chatCompletionsRequestSchema, handleBridgeChatCompletionRequest } = chatCompletionServiceModule;
5
+ const { FileBridgeStateStore } = fileBridgeStateStoreModule;
6
+ const { parseRequest } = parseRequestModule;
7
+ function registerChatCompletionRoute(app, context) {
8
+ const stateStore = new FileBridgeStateStore(context.config.stateRoot);
9
+ app.post("/v1/chat/completions", async (request, reply) => {
10
+ const body = parseRequest(chatCompletionsRequestSchema, request.body);
11
+ const execution = await handleBridgeChatCompletionRequest({
12
+ body,
13
+ headers: request.headers,
14
+ providerStore: context.providerStore,
15
+ service: context.service,
16
+ stateStore,
17
+ request: {
18
+ method: request.method,
19
+ url: request.url
20
+ },
21
+ onInternalError: context.onInternalError
22
+ });
23
+ if (execution.kind === "json") {
24
+ return execution.response;
25
+ }
26
+ reply.hijack();
27
+ reply.raw.writeHead(200, {
28
+ "Content-Type": "text/event-stream; charset=utf-8",
29
+ "Cache-Control": "no-store",
30
+ Connection: "keep-alive"
31
+ });
32
+ reply.raw.flushHeaders?.();
33
+ try {
34
+ for await (const event of execution.events) {
35
+ reply.raw.write(event === "[DONE]" ? "data: [DONE]\n\n" : formatSseData(event));
36
+ }
37
+ }
38
+ finally {
39
+ reply.raw.end();
40
+ }
41
+ return reply;
42
+ });
43
+ }
44
+ function formatSseData(value) {
45
+ return `data: ${JSON.stringify(value)}\n\n`;
46
+ }
47
+ export const chatCompletionsRouteModule = {
48
+ registerChatCompletionRoute
49
+ };
@@ -0,0 +1,6 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ declare function registerHealthRoutes(app: FastifyInstance): void;
3
+ export declare const healthRoutesModule: {
4
+ registerHealthRoutes: typeof registerHealthRoutes;
5
+ };
6
+ export {};
@@ -0,0 +1,7 @@
1
+ function registerHealthRoutes(app) {
2
+ app.get("/health", async () => ({ ok: true }));
3
+ app.get("/ready", async () => ({ ok: true }));
4
+ }
5
+ export const healthRoutesModule = {
6
+ registerHealthRoutes
7
+ };
@@ -0,0 +1,7 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ import type { BridgeApiRouteContext } from "../bridge-api-route-context.ts";
3
+ declare function registerMessageRoutes(app: FastifyInstance, context: BridgeApiRouteContext): void;
4
+ export declare const messageRoutesModule: {
5
+ registerMessageRoutes: typeof registerMessageRoutes;
6
+ };
7
+ export {};
@@ -0,0 +1,7 @@
1
+ function registerMessageRoutes(app, context) {
2
+ app.post("/v1/respond", async (request) => context.service.respond(request.body));
3
+ app.post("/v1/sessions/:sessionId/messages", async (request) => context.service.respond(request.body, request.params.sessionId));
4
+ }
5
+ export const messageRoutesModule = {
6
+ registerMessageRoutes
7
+ };
@@ -0,0 +1,85 @@
1
+ export declare const bridgeServer: {
2
+ BridgeApiHttpError: typeof import("./client/bridge-api-client.ts").BridgeApiHttpError;
3
+ buildHealthUrl: (baseUrl: string) => string;
4
+ buildSessionMessageUrl: (baseUrl: string, sessionId: string) => string;
5
+ checkBridgeHealth: (input: import("./client/bridge-api-client.ts").CheckBridgeHealthInput) => Promise<import("./shared/api-schema.ts").BridgeHealthResponse>;
6
+ sendBridgeMessage: (input: import("./client/bridge-api-client.ts").SendBridgeMessageInput) => Promise<import("./shared/api-schema.ts").BridgeMessageResponse>;
7
+ loadBridgeServerConfig: (env?: NodeJS.ProcessEnv, overrides?: import("./config/bridge-server-config.ts").BridgeServerConfigOverrides) => import("./config/bridge-server-config.ts").BridgeServerConfig;
8
+ BridgeApiError: typeof import("./shared/bridge-api-error.ts").BridgeApiError;
9
+ isBridgeApiError: (error: unknown) => error is import("./shared/bridge-api-error.ts").BridgeApiError;
10
+ DEFAULT_LIVE_CANARY_EXPECTED_SUBSTRING: string;
11
+ DEFAULT_LIVE_CANARY_PROMPT: string;
12
+ formatLiveProviderExtractionCanaryResult: (result: import("./bridge/live-provider-extraction-canary.ts").LiveProviderExtractionCanaryResult) => string;
13
+ runLiveProviderExtractionCanary: (input: import("./bridge/live-provider-extraction-canary.ts").LiveProviderExtractionCanaryInput) => Promise<import("./bridge/live-provider-extraction-canary.ts").LiveProviderExtractionCanaryResult>;
14
+ sanitizeBridgeApiOutput: (content: string) => import("@uncensoredcode/openbridge/runtime").VisibleModelOutputSanitizationResult;
15
+ createBridgeRuntimeService: (dependencies: import("./bridge/bridge-runtime-service.ts").BridgeRuntimeServiceDependencies) => {
16
+ respond(request: import("./shared/api-schema.ts").BridgeMessageRequest, pathSessionId?: string): Promise<import("./shared/api-schema.ts").BridgeMessageResponse>;
17
+ execute(request: {
18
+ sessionId: string;
19
+ input: string;
20
+ providerId: string;
21
+ modelId: string;
22
+ metadata?: Record<string, unknown>;
23
+ toolProfile?: import("./shared/api-schema.ts").BridgeApiToolProfile;
24
+ sessionHistory?: import("@uncensoredcode/openbridge/runtime").BridgeSessionTurn[];
25
+ persistSession?: boolean;
26
+ }): Promise<import("./shared/api-schema.ts").BridgeMessageResponse>;
27
+ completeChatCompletionPacket(request: {
28
+ sessionId: string;
29
+ providerId: string;
30
+ modelId: string;
31
+ messages: import("@uncensoredcode/openbridge/runtime").CompiledProviderMessage[];
32
+ tools: import("./shared/api-schema.ts").BridgeChatCompletionTool[];
33
+ toolChoice?: import("./shared/api-schema.ts").BridgeChatCompletionRequest["tool_choice"];
34
+ continuation: boolean;
35
+ toolFollowUp: boolean;
36
+ metadata?: Record<string, unknown>;
37
+ persistSession?: boolean;
38
+ }): Promise<{
39
+ packet: import("@uncensoredcode/openbridge/runtime").AssistantResponse;
40
+ providerBindingReused: boolean;
41
+ }>;
42
+ streamChatCompletionPacket(request: {
43
+ sessionId: string;
44
+ providerId: string;
45
+ modelId: string;
46
+ messages: import("@uncensoredcode/openbridge/runtime").CompiledProviderMessage[];
47
+ tools: import("./shared/api-schema.ts").BridgeChatCompletionTool[];
48
+ toolChoice?: import("./shared/api-schema.ts").BridgeChatCompletionRequest["tool_choice"];
49
+ continuation: boolean;
50
+ toolFollowUp: boolean;
51
+ metadata?: Record<string, unknown>;
52
+ persistSession?: boolean;
53
+ }): Promise<{
54
+ content: AsyncIterable<import("./bridge/providers/provider-streams.ts").ProviderStreamFragment>;
55
+ packet: Promise<import("@uncensoredcode/openbridge/runtime").AssistantResponse>;
56
+ providerBindingReused: boolean;
57
+ }>;
58
+ streamChatCompletion(request: {
59
+ sessionId: string;
60
+ input: string;
61
+ providerId: string;
62
+ modelId: string;
63
+ metadata?: Record<string, unknown>;
64
+ toolProfile?: import("./shared/api-schema.ts").BridgeApiToolProfile;
65
+ sessionHistory?: import("@uncensoredcode/openbridge/runtime").BridgeSessionTurn[];
66
+ persistSession?: boolean;
67
+ }): Promise<AsyncIterable<string>>;
68
+ };
69
+ createBridgeApiServer: (options?: import("./http/create-bridge-api-server.ts").BridgeApiServerOptions) => import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>;
70
+ startBridgeApiServer: (options?: import("./http/create-bridge-api-server.ts").BridgeApiServerOptions) => Promise<import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>>;
71
+ getBridgeServerCliHelpText: () => string;
72
+ parseBridgeServerCliArgs: (input: {
73
+ argv: string[];
74
+ env?: NodeJS.ProcessEnv;
75
+ }) => import("./cli/run-bridge-server-cli.ts").BridgeServerCliCommand;
76
+ runBridgeServerCli: (input: import("./cli/run-bridge-server-cli.ts").RunBridgeServerCliInput) => Promise<number>;
77
+ };
78
+ export type { LiveProviderExtractionCanaryInput, LiveProviderExtractionCanaryResult } from "./bridge/index.ts";
79
+ export type { BridgeRuntimeServiceDependencies } from "./bridge/index.ts";
80
+ export type { BridgeServerCliCommand, RunBridgeServerCliInput } from "./cli/index.ts";
81
+ export type { BridgeApiClientFetch, CheckBridgeHealthInput, SendBridgeMessageInput } from "./client/index.ts";
82
+ export type { BridgeServerConfig } from "./config/index.ts";
83
+ export type { BridgeApiServerOptions } from "./http/index.ts";
84
+ export type { BridgeApiErrorResponse, BridgeApiToolProfile, BridgeChatCompletionMessage, BridgeChatCompletionRequest, BridgeChatCompletionResponse, BridgeHealthResponse, BridgeMessageRequest, BridgeMessageResponse, BridgeReadyResponse } from "./shared/api-schema.ts";
85
+ export type { BridgeApiError } from "./shared/bridge-api-error.ts";
@@ -0,0 +1,28 @@
1
+ import { bridgeModule } from "./bridge/index.js";
2
+ import { cliModule } from "./cli/index.js";
3
+ import { clientModule } from "./client/index.js";
4
+ import { configModule } from "./config/index.js";
5
+ import { httpModule } from "./http/index.js";
6
+ import { bridgeApiErrorModule } from "./shared/bridge-api-error.js";
7
+ import { outputModule } from "./shared/output.js";
8
+ export const bridgeServer = {
9
+ BridgeApiHttpError: clientModule.BridgeApiHttpError,
10
+ buildHealthUrl: clientModule.buildHealthUrl,
11
+ buildSessionMessageUrl: clientModule.buildSessionMessageUrl,
12
+ checkBridgeHealth: clientModule.checkBridgeHealth,
13
+ sendBridgeMessage: clientModule.sendBridgeMessage,
14
+ loadBridgeServerConfig: configModule.loadBridgeServerConfig,
15
+ BridgeApiError: bridgeApiErrorModule.BridgeApiError,
16
+ isBridgeApiError: bridgeApiErrorModule.isBridgeApiError,
17
+ DEFAULT_LIVE_CANARY_EXPECTED_SUBSTRING: bridgeModule.DEFAULT_LIVE_CANARY_EXPECTED_SUBSTRING,
18
+ DEFAULT_LIVE_CANARY_PROMPT: bridgeModule.DEFAULT_LIVE_CANARY_PROMPT,
19
+ formatLiveProviderExtractionCanaryResult: bridgeModule.formatLiveProviderExtractionCanaryResult,
20
+ runLiveProviderExtractionCanary: bridgeModule.runLiveProviderExtractionCanary,
21
+ sanitizeBridgeApiOutput: outputModule.sanitizeBridgeApiOutput,
22
+ createBridgeRuntimeService: bridgeModule.createBridgeRuntimeService,
23
+ createBridgeApiServer: httpModule.createBridgeApiServer,
24
+ startBridgeApiServer: httpModule.startBridgeApiServer,
25
+ getBridgeServerCliHelpText: cliModule.getBridgeServerCliHelpText,
26
+ parseBridgeServerCliArgs: cliModule.parseBridgeServerCliArgs,
27
+ runBridgeServerCli: cliModule.runBridgeServerCli
28
+ };
@@ -0,0 +1,9 @@
1
+ import type { IncomingHttpHeaders } from "node:http";
2
+ import type { FastifyRequest } from "fastify";
3
+ declare function isAuthorizedBridgeRequest(headers: IncomingHttpHeaders, configuredToken: string | null | undefined): boolean;
4
+ declare function requiresBridgeAuth(request: FastifyRequest, configuredToken: string | null | undefined): boolean;
5
+ export declare const bridgeAuthModule: {
6
+ isAuthorizedBridgeRequest: typeof isAuthorizedBridgeRequest;
7
+ requiresBridgeAuth: typeof requiresBridgeAuth;
8
+ };
9
+ export {};
@@ -0,0 +1,41 @@
1
+ import { timingSafeEqual } from "node:crypto";
2
+ function isAuthorizedBridgeRequest(headers, configuredToken) {
3
+ if (!configuredToken) {
4
+ return true;
5
+ }
6
+ const providedToken = readBearerToken(headers.authorization) ?? readHeaderString(headers["x-bridge-token"]);
7
+ if (!providedToken) {
8
+ return false;
9
+ }
10
+ const expected = Buffer.from(configuredToken, "utf8");
11
+ const actual = Buffer.from(providedToken, "utf8");
12
+ if (expected.length !== actual.length) {
13
+ return false;
14
+ }
15
+ return timingSafeEqual(expected, actual);
16
+ }
17
+ function requiresBridgeAuth(request, configuredToken) {
18
+ if (!configuredToken) {
19
+ return false;
20
+ }
21
+ const pathname = request.raw.url?.split("?")[0] ?? request.url;
22
+ return pathname !== "/health" && pathname !== "/ready";
23
+ }
24
+ function readBearerToken(value) {
25
+ const normalized = readHeaderString(value);
26
+ if (!normalized || !/^Bearer\s+/i.test(normalized)) {
27
+ return null;
28
+ }
29
+ const token = normalized.replace(/^Bearer\s+/i, "").trim();
30
+ return token || null;
31
+ }
32
+ function readHeaderString(value) {
33
+ if (Array.isArray(value)) {
34
+ return value[0]?.trim() || null;
35
+ }
36
+ return value?.trim() || null;
37
+ }
38
+ export const bridgeAuthModule = {
39
+ isAuthorizedBridgeRequest,
40
+ requiresBridgeAuth
41
+ };
@@ -0,0 +1,5 @@
1
+ declare function resolveCorsOrigin(origin: string | undefined, configuredOrigins: string[] | undefined): string | null;
2
+ export declare const corsPolicyModule: {
3
+ resolveCorsOrigin: typeof resolveCorsOrigin;
4
+ };
5
+ export {};
@@ -0,0 +1,34 @@
1
+ import { configModule } from "../config/index.js";
2
+ const { isLocalBridgeHost, isWildcardCorsOrigins } = configModule;
3
+ function resolveCorsOrigin(origin, configuredOrigins) {
4
+ const normalizedOrigin = origin?.trim();
5
+ if (!normalizedOrigin) {
6
+ return null;
7
+ }
8
+ if (isWildcardCorsOrigins(configuredOrigins)) {
9
+ return "*";
10
+ }
11
+ if (configuredOrigins && configuredOrigins.length > 0) {
12
+ return configuredOrigins.includes(normalizedOrigin) ? normalizedOrigin : null;
13
+ }
14
+ return isDefaultAllowedCorsOrigin(normalizedOrigin) ? normalizedOrigin : null;
15
+ }
16
+ function isDefaultAllowedCorsOrigin(origin) {
17
+ let parsed;
18
+ try {
19
+ parsed = new URL(origin);
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ if (parsed.protocol === "chrome-extension:" || parsed.protocol === "moz-extension:") {
25
+ return true;
26
+ }
27
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
28
+ return false;
29
+ }
30
+ return isLocalBridgeHost(parsed.hostname);
31
+ }
32
+ export const corsPolicyModule = {
33
+ resolveCorsOrigin
34
+ };
@@ -0,0 +1,16 @@
1
+ export declare const securityModule: {
2
+ isAuthorizedBridgeRequest: (headers: import("node:http").IncomingHttpHeaders, configuredToken: string | null | undefined) => boolean;
3
+ requiresBridgeAuth: (request: import("fastify").FastifyRequest, configuredToken: string | null | undefined) => boolean;
4
+ resolveCorsOrigin: (origin: string | undefined, configuredOrigins: string[] | undefined) => string | null;
5
+ formatBridgeServerErrorLog: (error: unknown, context?: {
6
+ method?: string;
7
+ url?: string;
8
+ }) => string;
9
+ redactSensitiveValue: (value: unknown, path?: string[]) => unknown;
10
+ sanitizeBridgeApiErrorPayload: (error: import("../index.ts").BridgeApiError) => {
11
+ code: string;
12
+ message: string;
13
+ details: unknown;
14
+ };
15
+ sanitizeSensitiveText: (value: string) => string;
16
+ };
@@ -0,0 +1,12 @@
1
+ import { bridgeAuthModule } from "./bridge-auth.js";
2
+ import { corsPolicyModule } from "./cors-policy.js";
3
+ import { redactSensitiveValuesModule } from "./redact-sensitive-values.js";
4
+ export const securityModule = {
5
+ isAuthorizedBridgeRequest: bridgeAuthModule.isAuthorizedBridgeRequest,
6
+ requiresBridgeAuth: bridgeAuthModule.requiresBridgeAuth,
7
+ resolveCorsOrigin: corsPolicyModule.resolveCorsOrigin,
8
+ formatBridgeServerErrorLog: redactSensitiveValuesModule.formatBridgeServerErrorLog,
9
+ redactSensitiveValue: redactSensitiveValuesModule.redactSensitiveValue,
10
+ sanitizeBridgeApiErrorPayload: redactSensitiveValuesModule.sanitizeBridgeApiErrorPayload,
11
+ sanitizeSensitiveText: redactSensitiveValuesModule.sanitizeSensitiveText
12
+ };
@@ -0,0 +1,19 @@
1
+ import type { BridgeApiError } from "../shared/bridge-api-error.ts";
2
+ declare function sanitizeBridgeApiErrorPayload(error: BridgeApiError): {
3
+ code: string;
4
+ message: string;
5
+ details: unknown;
6
+ };
7
+ declare function formatBridgeServerErrorLog(error: unknown, context?: {
8
+ method?: string;
9
+ url?: string;
10
+ }): string;
11
+ declare function redactSensitiveValue(value: unknown, path?: string[]): unknown;
12
+ declare function sanitizeSensitiveText(value: string): string;
13
+ export declare const redactSensitiveValuesModule: {
14
+ sanitizeBridgeApiErrorPayload: typeof sanitizeBridgeApiErrorPayload;
15
+ formatBridgeServerErrorLog: typeof formatBridgeServerErrorLog;
16
+ redactSensitiveValue: typeof redactSensitiveValue;
17
+ sanitizeSensitiveText: typeof sanitizeSensitiveText;
18
+ };
19
+ export {};
@@ -0,0 +1,67 @@
1
+ const REDACTED = "[REDACTED]";
2
+ const SENSITIVE_KEY_PATTERN = /(authorization|headers?|cookie|cookies|set-cookie|localstorage|token|secret|bearer|session[-_]?package|extraheaders?|ciphertext|authtag|vaultkey|sessionvaultkey)/i;
3
+ function sanitizeBridgeApiErrorPayload(error) {
4
+ return {
5
+ code: error.code,
6
+ message: sanitizeSensitiveText(error.message),
7
+ details: error.details === undefined ? undefined : redactSensitiveValue(error.details)
8
+ };
9
+ }
10
+ function formatBridgeServerErrorLog(error, context = {}) {
11
+ const prefix = [
12
+ context.method && context.url ? `${context.method} ${context.url}` : (context.url ?? null),
13
+ "bridge-server error"
14
+ ]
15
+ .filter((segment) => Boolean(segment))
16
+ .join(": ");
17
+ if (typeof error === "object" && error !== null) {
18
+ const name = "name" in error && typeof error.name === "string" ? error.name : "Error";
19
+ const code = "code" in error && typeof error.code === "string" ? error.code : "";
20
+ const message = "message" in error && typeof error.message === "string" ? error.message : "";
21
+ const details = "details" in error && error.details !== undefined
22
+ ? ` details=${JSON.stringify(redactSensitiveValue(error.details))}`
23
+ : "";
24
+ return `${prefix}: ${sanitizeSensitiveText([name, code, message].filter(Boolean).join(" "))}${details}`;
25
+ }
26
+ return `${prefix}: ${sanitizeSensitiveText(String(error))}`;
27
+ }
28
+ function redactSensitiveValue(value, path = []) {
29
+ const currentKey = path.at(-1) ?? "";
30
+ if (isSensitiveKey(currentKey)) {
31
+ return REDACTED;
32
+ }
33
+ if (typeof value === "string") {
34
+ return sanitizeSensitiveText(value);
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.map((entry) => redactSensitiveValue(entry, path));
38
+ }
39
+ if (value && typeof value === "object") {
40
+ const result = {};
41
+ for (const [key, entry] of Object.entries(value)) {
42
+ result[key] = redactSensitiveValue(entry, [...path, key]);
43
+ }
44
+ return result;
45
+ }
46
+ return value;
47
+ }
48
+ function sanitizeSensitiveText(value) {
49
+ return value
50
+ .replace(/(Authorization\s*:\s*)Bearer\s+[^\s",]+/gi, "$1Bearer [REDACTED]")
51
+ .replace(/(["']authorization["']\s*:\s*["'])Bearer\s+[^"']+(["'])/gi, `$1Bearer ${REDACTED}$2`)
52
+ .replace(/Bearer\s+[^\s",]+/gi, "Bearer [REDACTED]")
53
+ .replace(/((?:cookie|set-cookie)\s*[:=]\s*)([^"'\n}]+)/gi, (_match, prefix, cookieHeader) => {
54
+ return `${prefix}${cookieHeader.replace(/([A-Za-z0-9._-]+\s*=)[^;,\s]+/g, `$1${REDACTED}`)}`;
55
+ })
56
+ .replace(/(["']?(?:token|access_token|refresh_token|bearerToken)["']?\s*[:=]\s*["']?)[^"',\s}]+/gi, `$1${REDACTED}`)
57
+ .replace(/((?:session|cookie)\s*=\s*)[^;\s",]+/gi, `$1${REDACTED}`);
58
+ }
59
+ function isSensitiveKey(value) {
60
+ return SENSITIVE_KEY_PATTERN.test(value);
61
+ }
62
+ export const redactSensitiveValuesModule = {
63
+ sanitizeBridgeApiErrorPayload,
64
+ formatBridgeServerErrorLog,
65
+ redactSensitiveValue,
66
+ sanitizeSensitiveText
67
+ };