pyric 0.1.0-alpha.19 → 0.1.0-alpha.21
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 +64 -89
- package/dist/ai/blocked.d.ts +52 -0
- package/dist/ai/blocked.d.ts.map +1 -0
- package/dist/ai/blocked.js +83 -0
- package/dist/ai/blocked.js.map +1 -0
- package/dist/ai/broker/broker.d.ts +50 -0
- package/dist/ai/broker/broker.d.ts.map +1 -1
- package/dist/ai/broker/broker.js +157 -21
- package/dist/ai/broker/broker.js.map +1 -1
- package/dist/ai/broker/gemini-engine.d.ts +56 -0
- package/dist/ai/broker/gemini-engine.d.ts.map +1 -0
- package/dist/ai/broker/gemini-engine.js +235 -0
- package/dist/ai/broker/gemini-engine.js.map +1 -0
- package/dist/ai/broker/index.d.ts +2 -1
- package/dist/ai/broker/index.d.ts.map +1 -1
- package/dist/ai/broker/index.js +2 -1
- package/dist/ai/broker/index.js.map +1 -1
- package/dist/ai/broker/openai-engine.d.ts +10 -1
- package/dist/ai/broker/openai-engine.d.ts.map +1 -1
- package/dist/ai/broker/openai-engine.js +26 -4
- package/dist/ai/broker/openai-engine.js.map +1 -1
- package/dist/ai/broker/synthesizer.d.ts +14 -0
- package/dist/ai/broker/synthesizer.d.ts.map +1 -1
- package/dist/ai/broker/synthesizer.js +31 -0
- package/dist/ai/broker/synthesizer.js.map +1 -1
- package/dist/ai/broker/types.d.ts +29 -0
- package/dist/ai/broker/types.d.ts.map +1 -1
- package/dist/ai/instances.js +1 -1
- package/dist/ai/instances.js.map +1 -1
- package/dist/ai/internal.d.ts +5 -0
- package/dist/ai/internal.d.ts.map +1 -1
- package/dist/ai/internal.js +5 -0
- package/dist/ai/internal.js.map +1 -1
- package/dist/ai/response-helpers.d.ts.map +1 -1
- package/dist/ai/response-helpers.js +6 -24
- package/dist/ai/response-helpers.js.map +1 -1
- package/dist/analytics/index.d.ts +40 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +25 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/app-check/index.d.ts +31 -0
- package/dist/app-check/index.d.ts.map +1 -0
- package/dist/app-check/index.js +20 -0
- package/dist/app-check/index.js.map +1 -0
- package/dist/auth/instances.js +1 -1
- package/dist/auth/instances.js.map +1 -1
- package/dist/database/controls.d.ts +1 -1
- package/dist/database/controls.js +1 -1
- package/dist/database/instances.js +1 -1
- package/dist/database/instances.js.map +1 -1
- package/dist/database/sandbox/backend.d.ts +1 -0
- package/dist/database/sandbox/backend.d.ts.map +1 -1
- package/dist/database/sandbox/backend.js +1 -0
- package/dist/database/sandbox/backend.js.map +1 -1
- package/dist/database/sandbox/rules-eval.d.ts +6 -2
- package/dist/database/sandbox/rules-eval.d.ts.map +1 -1
- package/dist/database/sandbox/rules-eval.js +15 -2
- package/dist/database/sandbox/rules-eval.js.map +1 -1
- package/dist/database/sandbox/write-plane.d.ts +1 -0
- package/dist/database/sandbox/write-plane.d.ts.map +1 -1
- package/dist/database/sandbox/write-plane.js +7 -2
- package/dist/database/sandbox/write-plane.js.map +1 -1
- package/dist/database/sandbox-controls.d.ts +12 -5
- package/dist/database/sandbox-controls.d.ts.map +1 -1
- package/dist/database/sandbox-controls.js +20 -9
- package/dist/database/sandbox-controls.js.map +1 -1
- package/dist/database/sandbox-namespace.d.ts +19 -1
- package/dist/database/sandbox-namespace.d.ts.map +1 -1
- package/dist/database/sandbox-namespace.js +24 -1
- package/dist/database/sandbox-namespace.js.map +1 -1
- package/dist/deferred/entry.d.ts +75 -0
- package/dist/deferred/entry.d.ts.map +1 -0
- package/dist/deferred/entry.js +143 -0
- package/dist/deferred/entry.js.map +1 -0
- package/dist/firestore/instances.js +1 -1
- package/dist/firestore/instances.js.map +1 -1
- package/dist/firestore/lite.d.ts +72 -0
- package/dist/firestore/lite.d.ts.map +1 -0
- package/dist/firestore/lite.js +22 -0
- package/dist/firestore/lite.js.map +1 -0
- package/dist/firestore/persistence.d.ts +2 -2
- package/dist/firestore/persistence.js +1 -1
- package/dist/firestore/sandbox-controls.d.ts +2 -0
- package/dist/firestore/sandbox-controls.d.ts.map +1 -1
- package/dist/firestore/sandbox-controls.js +8 -0
- package/dist/firestore/sandbox-controls.js.map +1 -1
- package/dist/functions/index.d.ts +29 -0
- package/dist/functions/index.d.ts.map +1 -0
- package/dist/functions/index.js +20 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/messaging/client.d.ts +2 -1
- package/dist/messaging/client.d.ts.map +1 -1
- package/dist/messaging/client.js +2 -2
- package/dist/messaging/client.js.map +1 -1
- package/dist/messaging/instance.d.ts +2 -2
- package/dist/messaging/instance.d.ts.map +1 -1
- package/dist/messaging/instance.js +40 -6
- package/dist/messaging/instance.js.map +1 -1
- package/dist/messaging/sw.d.ts +2 -1
- package/dist/messaging/sw.d.ts.map +1 -1
- package/dist/messaging/sw.js +2 -2
- package/dist/messaging/sw.js.map +1 -1
- package/dist/performance/index.d.ts +22 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +19 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/remote-config/index.d.ts +40 -0
- package/dist/remote-config/index.d.ts.map +1 -0
- package/dist/remote-config/index.js +25 -0
- package/dist/remote-config/index.js.map +1 -0
- package/dist/rules/grammar/FirestoreValidator.d.ts.map +1 -1
- package/dist/rules/grammar/FirestoreValidator.js +43 -27
- package/dist/rules/grammar/FirestoreValidator.js.map +1 -1
- package/dist/rules/grammar/document-access-count.d.ts +24 -0
- package/dist/rules/grammar/document-access-count.d.ts.map +1 -0
- package/dist/rules/grammar/document-access-count.js +100 -0
- package/dist/rules/grammar/document-access-count.js.map +1 -0
- package/dist/rules/linter/ast-utils.d.ts +2 -6
- package/dist/rules/linter/ast-utils.d.ts.map +1 -1
- package/dist/rules/linter/ast-utils.js +2 -63
- package/dist/rules/linter/ast-utils.js.map +1 -1
- package/dist/rules/linter/hallucinations.d.ts +8 -0
- package/dist/rules/linter/hallucinations.d.ts.map +1 -1
- package/dist/rules/linter/hallucinations.js +121 -31
- package/dist/rules/linter/hallucinations.js.map +1 -1
- package/dist/rules/linter/linter.d.ts +10 -1
- package/dist/rules/linter/linter.d.ts.map +1 -1
- package/dist/rules/linter/linter.js +23 -9
- package/dist/rules/linter/linter.js.map +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm +5 -2
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js +5 -2
- package/dist/rules/rtdb/grammar/RtdbExpr.ohm.generated.js.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.d.ts.map +1 -1
- package/dist/rules/rtdb/grammar/simulator.js +61 -15
- package/dist/rules/rtdb/grammar/simulator.js.map +1 -1
- package/dist/rules/rtdb/simulation/handler.d.ts.map +1 -1
- package/dist/rules/rtdb/simulation/handler.js +96 -35
- package/dist/rules/rtdb/simulation/handler.js.map +1 -1
- package/dist/rules/simulator/document-lookups.d.ts +4 -0
- package/dist/rules/simulator/document-lookups.d.ts.map +1 -1
- package/dist/rules/simulator/document-lookups.js +42 -3
- package/dist/rules/simulator/document-lookups.js.map +1 -1
- package/dist/rules/simulator/eval-error.d.ts +11 -0
- package/dist/rules/simulator/eval-error.d.ts.map +1 -1
- package/dist/rules/simulator/eval-error.js +14 -0
- package/dist/rules/simulator/eval-error.js.map +1 -1
- package/dist/rules/simulator/evaluation-builtins.d.ts.map +1 -1
- package/dist/rules/simulator/evaluation-builtins.js +33 -8
- package/dist/rules/simulator/evaluation-builtins.js.map +1 -1
- package/dist/rules/simulator/evaluation-context.d.ts +12 -0
- package/dist/rules/simulator/evaluation-context.d.ts.map +1 -1
- package/dist/rules/simulator/evaluator.d.ts +1 -1
- package/dist/rules/simulator/evaluator.d.ts.map +1 -1
- package/dist/rules/simulator/evaluator.js +16 -4
- package/dist/rules/simulator/evaluator.js.map +1 -1
- package/dist/rules/simulator/handler.d.ts.map +1 -1
- package/dist/rules/simulator/handler.js +52 -5
- package/dist/rules/simulator/handler.js.map +1 -1
- package/dist/rules/simulator/lookup-budget.d.ts +37 -0
- package/dist/rules/simulator/lookup-budget.d.ts.map +1 -0
- package/dist/rules/simulator/lookup-budget.js +96 -0
- package/dist/rules/simulator/lookup-budget.js.map +1 -0
- package/dist/rules/stdlib-modules.d.ts +7 -0
- package/dist/rules/stdlib-modules.d.ts.map +1 -1
- package/dist/rules/stdlib-modules.js +11 -11
- package/dist/rules/stdlib-modules.js.map +1 -1
- package/dist/sandbox/admin-firestore/get-firestore.d.ts +6 -0
- package/dist/sandbox/admin-firestore/get-firestore.d.ts.map +1 -1
- package/dist/sandbox/admin-firestore/get-firestore.js +22 -3
- package/dist/sandbox/admin-firestore/get-firestore.js.map +1 -1
- package/dist/sandbox/index.d.ts +1 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +1 -1
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/persistence/types.d.ts +1 -1
- package/dist/sandbox/remote.d.ts +2 -2
- package/dist/sandbox/sandbox-context.d.ts +8 -1
- package/dist/sandbox/sandbox-context.d.ts.map +1 -1
- package/dist/sandbox/sandbox-context.js +59 -8
- package/dist/sandbox/sandbox-context.js.map +1 -1
- package/dist/sandbox/types/auth-state.d.ts +1 -0
- package/dist/sandbox/types/auth-state.d.ts.map +1 -1
- package/dist/sandbox/types/events.d.ts +2 -1
- package/dist/sandbox/types/events.d.ts.map +1 -1
- package/dist/sandbox/types/operation.d.ts +1 -0
- package/dist/sandbox/types/operation.d.ts.map +1 -1
- package/dist/storage/enforce.d.ts +20 -1
- package/dist/storage/enforce.d.ts.map +1 -1
- package/dist/storage/enforce.js +47 -14
- package/dist/storage/enforce.js.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/list.js +1 -1
- package/dist/storage/list.js.map +1 -1
- package/dist/storage/persistence.d.ts.map +1 -1
- package/dist/storage/persistence.js +66 -14
- package/dist/storage/persistence.js.map +1 -1
- package/dist/storage/sandbox/rules-evaluation-error.d.ts +25 -0
- package/dist/storage/sandbox/rules-evaluation-error.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-evaluation-error.js +29 -0
- package/dist/storage/sandbox/rules-evaluation-error.js.map +1 -1
- package/dist/storage/sandbox/rules-evaluator.d.ts +10 -5
- package/dist/storage/sandbox/rules-evaluator.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-evaluator.js +105 -33
- package/dist/storage/sandbox/rules-evaluator.js.map +1 -1
- package/dist/storage/sandbox/rules-methods.d.ts.map +1 -1
- package/dist/storage/sandbox/rules-methods.js +17 -7
- package/dist/storage/sandbox/rules-methods.js.map +1 -1
- package/dist/storage/service.d.ts +23 -2
- package/dist/storage/service.d.ts.map +1 -1
- package/dist/storage/service.js +37 -26
- package/dist/storage/service.js.map +1 -1
- package/package.json +42 -2
- package/src/ai/blocked.ts +97 -0
- package/src/ai/broker/broker.ts +153 -22
- package/src/ai/broker/gemini-engine.ts +311 -0
- package/src/ai/broker/index.ts +2 -0
- package/src/ai/broker/openai-engine.ts +31 -3
- package/src/ai/broker/synthesizer.ts +34 -0
- package/src/ai/broker/types.ts +27 -1
- package/src/ai/instances.ts +1 -1
- package/src/ai/internal.ts +5 -0
- package/src/ai/response-helpers.ts +6 -25
- package/src/analytics/index.ts +53 -0
- package/src/app/dispatch.test.ts +3 -1
- package/src/app-check/index.ts +41 -0
- package/src/auth/instances.ts +1 -1
- package/src/database/controls.ts +1 -1
- package/src/database/instances.ts +1 -1
- package/src/database/sandbox/backend.ts +1 -0
- package/src/database/sandbox/rules-eval.ts +18 -2
- package/src/database/sandbox/write-plane.ts +8 -2
- package/src/database/sandbox-controls.ts +29 -9
- package/src/database/sandbox-namespace.ts +28 -1
- package/src/deferred/entry.ts +167 -0
- package/src/firestore/instances.ts +1 -1
- package/src/firestore/lite.ts +91 -0
- package/src/firestore/persistence.ts +2 -2
- package/src/firestore/sandbox-controls.ts +10 -0
- package/src/functions/index.ts +38 -0
- package/src/messaging/client.ts +3 -2
- package/src/messaging/instance.ts +44 -7
- package/src/messaging/sw.ts +3 -2
- package/src/performance/index.ts +31 -0
- package/src/remote-config/index.ts +53 -0
- package/src/rules/grammar/FirestoreValidator.ts +44 -28
- package/src/rules/grammar/document-access-count.ts +75 -0
- package/src/rules/linter/ast-utils.ts +2 -36
- package/src/rules/linter/hallucinations.ts +123 -25
- package/src/rules/linter/linter.ts +32 -10
- package/src/rules/rtdb/grammar/RtdbExpr.ohm +5 -2
- package/src/rules/rtdb/grammar/RtdbExpr.ohm.generated.ts +5 -2
- package/src/rules/rtdb/grammar/simulator.ts +41 -15
- package/src/rules/rtdb/simulation/handler.ts +149 -46
- package/src/rules/simulator/document-lookups.ts +46 -3
- package/src/rules/simulator/eval-error.ts +16 -0
- package/src/rules/simulator/evaluation-builtins.ts +35 -8
- package/src/rules/simulator/evaluation-context.ts +12 -0
- package/src/rules/simulator/evaluator.ts +14 -3
- package/src/rules/simulator/handler.ts +68 -4
- package/src/rules/simulator/lookup-budget.ts +101 -0
- package/src/rules/stdlib-modules.ts +19 -11
- package/src/sandbox/admin-firestore/get-firestore.ts +19 -3
- package/src/sandbox/index.ts +5 -1
- package/src/sandbox/persistence/types.ts +1 -1
- package/src/sandbox/remote.ts +2 -2
- package/src/sandbox/sandbox-context.ts +69 -9
- package/src/sandbox/types/auth-state.ts +1 -1
- package/src/sandbox/types/events.ts +2 -1
- package/src/sandbox/types/operation.ts +1 -1
- package/src/storage/enforce.ts +53 -14
- package/src/storage/index.ts +1 -1
- package/src/storage/list.ts +1 -1
- package/src/storage/persistence.ts +74 -16
- package/src/storage/sandbox/rules-evaluation-error.ts +32 -0
- package/src/storage/sandbox/rules-evaluator.ts +109 -32
- package/src/storage/sandbox/rules-methods.ts +21 -7
- package/src/storage/service.ts +93 -27
- package/README.md.orig +0 -53
package/README.md
CHANGED
|
@@ -2,50 +2,39 @@
|
|
|
2
2
|
<img src="https://pyric.dev/pyric-logo.svg" alt="Pyric" width="180" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
<h1 align="center">A
|
|
5
|
+
<h1 align="center">A Firebase that runs inside your app</h1>
|
|
6
6
|
|
|
7
|
-
<p align="center">Keep the same <code>firebase/*</code> code.
|
|
7
|
+
<p align="center">Keep the same <code>firebase/*</code> code. During <code>vite dev</code> those imports resolve to a local backend running in the page. A production build ships the real Firebase SDK, unchanged.</p>
|
|
8
8
|
|
|
9
9
|
<p align="center"><a href="https://pyric.dev">pyric.dev</a></p>
|
|
10
10
|
|
|
11
11
|
<br />
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Application code stays canonical Firebase:
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npx plugins add davideast/pyric
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
Antigravity CLI and OpenCode use the standalone skill installer:
|
|
15
|
+
```ts
|
|
16
|
+
// src/firebase.ts
|
|
17
|
+
import { initializeApp } from 'firebase/app';
|
|
18
|
+
import { getAuth } from 'firebase/auth';
|
|
19
|
+
import { getFirestore } from 'firebase/firestore';
|
|
26
20
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
const app = initializeApp({
|
|
22
|
+
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
|
|
23
|
+
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
|
|
24
|
+
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
|
|
25
|
+
});
|
|
30
26
|
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
export const auth = getAuth(app);
|
|
28
|
+
export const db = getFirestore(app);
|
|
33
29
|
```
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
Run the Vite development server and supported Firebase imports resolve to a browser-local backend: Auth, Firestore with Security Rules, persistence in IndexedDB, one SharedWorker backend shared by every tab on the dev origin. Run a normal production build and those imports resolve to Firebase again. The application source does not branch between the two, and the local mirror never connects to a production project.
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|---|---|
|
|
39
|
-
| Codex | `$pyric-start` |
|
|
40
|
-
| Claude Code | `/pyric:pyric-start` |
|
|
41
|
-
| Antigravity CLI | `/pyric-start` |
|
|
42
|
-
| OpenCode | `/pyric-start` |
|
|
33
|
+
Coding agents get the same backend. A [skill](#start-with-a-coding-agent) sets up the sandbox end to end (`npx plugins add davideast/pyric`, then `/pyric`), and an opt-in MCP bridge lets an agent seed, inspect, and change the backend the app is already running against. `can-i-use` answers what conforms to real Firebase before the agent builds on it.
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
The skill chooses the project launcher, starts one local sandbox bridge, opens the application, and confirms that the browser sandbox is connected.
|
|
35
|
+
<img width="1512" height="947" alt="Pyric Studio showing local data, requests, authentication state, and Security Rules verdicts" src="https://github.com/user-attachments/assets/cb4a219c-c5f0-4fb7-8904-996416c0a79c" />
|
|
47
36
|
|
|
48
|
-
##
|
|
37
|
+
## Create a new app
|
|
49
38
|
|
|
50
39
|
Create a Vite application with canonical Firebase imports, Firestore rules, and the Pyric development plugin already configured:
|
|
51
40
|
|
|
@@ -82,70 +71,69 @@ Start the normal development server:
|
|
|
82
71
|
npm run dev
|
|
83
72
|
```
|
|
84
73
|
|
|
85
|
-
During `vite dev`, the plugin swaps supported `firebase/*` modules at resolution time.
|
|
74
|
+
During `vite dev`, the plugin swaps supported `firebase/*` modules at resolution time. Pyric Studio is available on the Vite origin at `/__pyric/ui/studio`. It opens the same backend used by the application.
|
|
86
75
|
|
|
87
|
-
|
|
76
|
+
For a static application or a Node process, `pyric sandbox` provides the same development-only package swap without the Vite plugin. The [CLI reference](packages/site-docs/src/content/reference/cli.md) documents those paths and every command.
|
|
88
77
|
|
|
89
|
-
|
|
78
|
+
## Start with a coding agent
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
Install the Pyric plugin:
|
|
92
81
|
|
|
93
|
-
|
|
82
|
+
```bash
|
|
83
|
+
npx plugins add davideast/pyric
|
|
84
|
+
```
|
|
94
85
|
|
|
95
|
-
|
|
96
|
-
// src/firebase.ts
|
|
97
|
-
import { initializeApp } from 'firebase/app';
|
|
98
|
-
import { getAuth } from 'firebase/auth';
|
|
99
|
-
import { getFirestore } from 'firebase/firestore';
|
|
86
|
+
Antigravity CLI and OpenCode use the standalone skill installer:
|
|
100
87
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
|
|
105
|
-
});
|
|
88
|
+
```bash
|
|
89
|
+
# Antigravity CLI
|
|
90
|
+
npx skills add https://github.com/davideast/pyric/tree/main/pyric-plugin/skills/pyric --agent antigravity-cli
|
|
106
91
|
|
|
107
|
-
|
|
108
|
-
|
|
92
|
+
# OpenCode
|
|
93
|
+
npx skills add https://github.com/davideast/pyric/tree/main/pyric-plugin/skills/pyric --agent opencode
|
|
109
94
|
```
|
|
110
95
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Pyric documents the parts that differ locally, including supported behavior, Security Rules, persistence, inspection, verification, and known gaps. See [use the Vite plugin](packages/cli/docs/how-to/use-the-vite-plugin.md) for the complete plugin contract.
|
|
114
|
-
|
|
115
|
-
## Monitor the local environment in Pyric Studio
|
|
96
|
+
Then invoke the skill:
|
|
116
97
|
|
|
117
|
-
|
|
98
|
+
| Agent | Enter |
|
|
99
|
+
|---|---|
|
|
100
|
+
| Codex | `$pyric` |
|
|
101
|
+
| Claude Code | `/pyric:pyric` |
|
|
102
|
+
| Antigravity CLI | `/pyric` |
|
|
103
|
+
| OpenCode | `/pyric` |
|
|
118
104
|
|
|
119
|
-
|
|
105
|
+
The leading `$` or `/` is part of the command.
|
|
120
106
|
|
|
121
|
-
The
|
|
107
|
+
The skill chooses the project launcher, starts one local sandbox bridge, opens the application, and confirms that the browser sandbox is connected.
|
|
122
108
|
|
|
123
|
-
|
|
109
|
+
An agent can also work through the MCP bridge directly. It keeps writing the same Firebase code while inspecting and changing the backend the application is already using. Agent access is opt-in:
|
|
124
110
|
|
|
125
111
|
```ts
|
|
126
112
|
pyric({
|
|
127
|
-
|
|
128
|
-
seed: 'seed.json',
|
|
113
|
+
bridge: true
|
|
129
114
|
});
|
|
130
115
|
```
|
|
131
116
|
|
|
132
|
-
|
|
117
|
+
The bridge mounts on the Vite development origin and routes agent operations to the same SharedWorker backend used by the application and Studio. This protects the local workflow, not an independently credentialed process. A coding agent with production Firebase credentials or deployment access can still affect production outside Pyric.
|
|
118
|
+
|
|
119
|
+
## Monitor the local environment in Pyric Studio
|
|
120
|
+
|
|
121
|
+
Pyric Studio shows local data, requests, authentication state, Security Rules verdicts, and denied operations. Open `/__pyric/ui/studio` on the development server and reproduce the failure. A denied request includes the path and verdict needed to correct the rule or the application code.
|
|
133
122
|
|
|
134
|
-
|
|
123
|
+
The Vite plugin discovers the Firestore rules path from `firebase.json`, or falls back to `firestore.rules`. Saving that file replaces the active local ruleset without a production deploy. A parse failure leaves the last valid ruleset active and reports the error in the development server.
|
|
135
124
|
|
|
136
|
-
|
|
125
|
+
State and test identities stay browser-local by default. Add `persist: true` to write a committable `.pyric/state/state.json`, or use `seed` to start from a known scenario:
|
|
137
126
|
|
|
138
127
|
```ts
|
|
139
|
-
pyric({
|
|
140
|
-
|
|
128
|
+
pyric({
|
|
129
|
+
persist: true,
|
|
130
|
+
seed: 'seed.json',
|
|
141
131
|
});
|
|
142
132
|
```
|
|
143
133
|
|
|
144
|
-
|
|
134
|
+
See [persistence and multi-tab behavior](packages/site-docs/src/content/observe/shape-your-data.md) for reset and seed precedence.
|
|
145
135
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
## Verify the rules against production
|
|
136
|
+
## Verify the rules against production
|
|
149
137
|
|
|
150
138
|
Development sessions capture Firestore and Realtime Database operations in `.pyric/last-session.json` by default. Replay those requests against candidate rules before deployment:
|
|
151
139
|
|
|
@@ -153,7 +141,7 @@ Development sessions capture Firestore and Realtime Database operations in `.pyr
|
|
|
153
141
|
npx pyric verify
|
|
154
142
|
```
|
|
155
143
|
|
|
156
|
-
The default engine runs locally. The optional Firestore Rules Test API engine sends derived rule cases to Google's hosted evaluator when production-authority verification is needed. It verifies rules and does not deploy them. See [verify against a captured session](packages/
|
|
144
|
+
The default engine runs locally. The optional Firestore Rules Test API engine sends derived rule cases to Google's hosted evaluator when production-authority verification is needed. It verifies rules and does not deploy them. See [verify against a captured session](packages/site-docs/src/content/ship/ship-to-production.md).
|
|
157
145
|
|
|
158
146
|
## Ship the same application code
|
|
159
147
|
|
|
@@ -165,37 +153,24 @@ npm run build
|
|
|
165
153
|
|
|
166
154
|
The built application contains the real Firebase SDK and uses the Firebase configuration already present in the source. Deploy the build, rules, and indexes with `firebase-tools` or the Firebase Console. Pyric has no production deployment path.
|
|
167
155
|
|
|
156
|
+
The mirrored data services do not connect to a production Firebase project. Local writes cannot delete production data or create Firebase usage charges, and local rules changes do not deploy. Pyric owns the development sandbox and verification workflow. Firebase owns production, with `firebase-tools` or the Firebase Console handling deployment.
|
|
157
|
+
|
|
158
|
+
Normal Auth, Firestore, Realtime Database, Storage, Messaging, and Firebase AI Logic usage still belongs in the [Firebase documentation](https://firebase.google.com/docs). Pyric documents the parts that differ locally, including supported behavior, Security Rules, persistence, inspection, verification, and known gaps. See [use the Vite plugin](packages/site-docs/src/content/get-started/vite.md) for the complete plugin contract.
|
|
159
|
+
|
|
168
160
|
## Check what Pyric mirrors
|
|
169
161
|
|
|
170
162
|
Pyric is an independent implementation of observable Firebase behavior. Conformance evidence records what has been compared with Firebase and keeps five outcomes distinct: conforms, documented divergence, bug, unsupported, and unverified. The evidence is a floor, not a claim that every Firebase behavior has been measured.
|
|
171
163
|
|
|
172
|
-
Ask about a developer-facing feature
|
|
164
|
+
Ask about a developer-facing feature:
|
|
173
165
|
|
|
174
166
|
```bash
|
|
175
167
|
npx pyric can-i-use getAfter
|
|
176
168
|
npx pyric can-i-use firestore-rules/request.query --json
|
|
177
169
|
```
|
|
178
170
|
|
|
179
|
-
The result reports availability, Firebase fidelity, and assurance eligibility as separate axes. Exact names succeed;
|
|
180
|
-
|
|
181
|
-
Documentation and other Node consumers can bind the same feature name to the
|
|
182
|
-
published import that exposes it, without maintaining a second surface map:
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
import { canIUse, canIUseImport } from '@pyric/cli/conformance';
|
|
186
|
-
|
|
187
|
-
const result = canIUse('getDownloadURL', { importPath: 'pyric/storage' });
|
|
188
|
-
const evidence = canIUseImport('pyric/storage');
|
|
189
|
-
const evidencePage = evidence && `/docs/${evidence.evidenceSlug}/`;
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Each support result carries only census-proven `importPaths`; registry ownership
|
|
193
|
-
cannot invent package exports. `canIUseImport()` supplies the separate canonical
|
|
194
|
-
import-to-evidence join used by generated API documentation. An unrelated
|
|
195
|
-
import path returns no exact match rather than borrowing another surface's trust
|
|
196
|
-
claim.
|
|
171
|
+
The result reports availability, Firebase fidelity, and assurance eligibility as separate axes. Exact names succeed; fuzzy input prints labeled suggestions and exits nonzero instead of presenting a guess as a trust answer.
|
|
197
172
|
|
|
198
|
-
Read the generated [conformance scores](https://pyric.dev/docs/conformance-scores/) and the service matrices in the site's Conformance section. They are built from the same canonical registry used by assurance and `canIUse
|
|
173
|
+
Read the generated [conformance scores](https://pyric.dev/docs/conformance-scores/) and the service matrices in the site's Conformance section. They are built from the same canonical registry used by assurance and `canIUse`. Node consumers can query the same registry through [`@pyric/cli/conformance`](packages/site-docs/src/content/reference/cli.md). The [versioning and compatibility policy](packages/site-docs/src/content/trust/versioning-and-compatibility.md) explains the release boundary.
|
|
199
174
|
|
|
200
175
|
## Stability
|
|
201
176
|
|
|
@@ -212,4 +187,4 @@ bun run test
|
|
|
212
187
|
bun run compat:check
|
|
213
188
|
```
|
|
214
189
|
|
|
215
|
-
See [
|
|
190
|
+
See [CONTEXT.md](CONTEXT.md) and [AGENTS.md](AGENTS.md) before changing the codebase.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocked-response detection: the ONE definition of "this envelope carries
|
|
3
|
+
* no usable content because a filter fired", shared by the two places that
|
|
4
|
+
* need it:
|
|
5
|
+
*
|
|
6
|
+
* - `response-helpers.ts`, which throws upstream's exact
|
|
7
|
+
* `Response error: Candidate was blocked due to <reason>` out of
|
|
8
|
+
* `text()` / `functionCalls()` / `inlineDataParts()` when the caller
|
|
9
|
+
* reaches for content that isn't there;
|
|
10
|
+
* - `broker/broker.ts`, which lands a `response_blocked` event on the
|
|
11
|
+
* sandbox's unified stream at RESPONSE time, so the block is visible
|
|
12
|
+
* even when nobody ever calls `text()` (an app that renders
|
|
13
|
+
* `response.text ?? ''` used to show an empty bubble and nothing else).
|
|
14
|
+
*
|
|
15
|
+
* A block is not a rejection: production answers HTTP 200 with an empty
|
|
16
|
+
* candidate and the reason in `finishReason` (SAFETY, RECITATION,
|
|
17
|
+
* BLOCKLIST, PROHIBITED_CONTENT, SPII, the IMAGE_* variants), or, when the
|
|
18
|
+
* PROMPT itself was refused, with no candidates at all and a
|
|
19
|
+
* `promptFeedback.blockReason`. Nothing throws on the wire path.
|
|
20
|
+
*
|
|
21
|
+
* Leaf module by construction: it imports only `./enums.js` (which imports
|
|
22
|
+
* nothing) and a type. `broker/` must NOT reach into `response-helpers.ts`
|
|
23
|
+
* for this: that file pulls `./errors.js`, which imports `./broker/index.js`
|
|
24
|
+
* as a value, and the round trip would be a real runtime cycle.
|
|
25
|
+
*/
|
|
26
|
+
import type { WireResponse } from './broker/types.js';
|
|
27
|
+
/** Does this candidate's finish reason mean the content was withheld? */
|
|
28
|
+
export declare function isBlockingFinishReason(finishReason: string | undefined): boolean;
|
|
29
|
+
/** What a block was, in the wire's own vocabulary. Exactly one of
|
|
30
|
+
* `finishReason` (a candidate was withheld) / `blockReason` (the prompt was
|
|
31
|
+
* refused) is normally set; both may be absent when production sent
|
|
32
|
+
* `promptFeedback` with no reason at all. */
|
|
33
|
+
export interface ResponseBlock {
|
|
34
|
+
/** Candidate-level: the blocking `finishReason` off candidate 0. */
|
|
35
|
+
finishReason?: string;
|
|
36
|
+
/** Candidate-level: production's own explanatory `finishMessage`. */
|
|
37
|
+
finishMessage?: string;
|
|
38
|
+
/** Prompt-level: `promptFeedback.blockReason`. */
|
|
39
|
+
blockReason?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Classify an envelope, mirroring `hasValidCandidates` in
|
|
43
|
+
* `response-helpers.ts` EXACTLY so the event stream and the thrown error can
|
|
44
|
+
* never disagree: candidate 0 with a blocking finish reason is a block; no
|
|
45
|
+
* candidate 0 at all plus any `promptFeedback` is a block; everything else
|
|
46
|
+
* (including a plain `STOP` or `MAX_TOKENS`) is not.
|
|
47
|
+
*
|
|
48
|
+
* Returns `null` when the response is fine, so a caller reads as
|
|
49
|
+
* `const block = describeResponseBlock(res); if (block !== null) …`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function describeResponseBlock(response: WireResponse): ResponseBlock | null;
|
|
52
|
+
//# sourceMappingURL=blocked.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked.d.ts","sourceRoot":"","sources":["../../src/ai/blocked.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA4BtD,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGhF;AAED;;;8CAG8C;AAC9C,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,aAAa,GAAG,IAAI,CAalF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocked-response detection: the ONE definition of "this envelope carries
|
|
3
|
+
* no usable content because a filter fired", shared by the two places that
|
|
4
|
+
* need it:
|
|
5
|
+
*
|
|
6
|
+
* - `response-helpers.ts`, which throws upstream's exact
|
|
7
|
+
* `Response error: Candidate was blocked due to <reason>` out of
|
|
8
|
+
* `text()` / `functionCalls()` / `inlineDataParts()` when the caller
|
|
9
|
+
* reaches for content that isn't there;
|
|
10
|
+
* - `broker/broker.ts`, which lands a `response_blocked` event on the
|
|
11
|
+
* sandbox's unified stream at RESPONSE time, so the block is visible
|
|
12
|
+
* even when nobody ever calls `text()` (an app that renders
|
|
13
|
+
* `response.text ?? ''` used to show an empty bubble and nothing else).
|
|
14
|
+
*
|
|
15
|
+
* A block is not a rejection: production answers HTTP 200 with an empty
|
|
16
|
+
* candidate and the reason in `finishReason` (SAFETY, RECITATION,
|
|
17
|
+
* BLOCKLIST, PROHIBITED_CONTENT, SPII, the IMAGE_* variants), or, when the
|
|
18
|
+
* PROMPT itself was refused, with no candidates at all and a
|
|
19
|
+
* `promptFeedback.blockReason`. Nothing throws on the wire path.
|
|
20
|
+
*
|
|
21
|
+
* Leaf module by construction: it imports only `./enums.js` (which imports
|
|
22
|
+
* nothing) and a type. `broker/` must NOT reach into `response-helpers.ts`
|
|
23
|
+
* for this: that file pulls `./errors.js`, which imports `./broker/index.js`
|
|
24
|
+
* as a value, and the round trip would be a real runtime cycle.
|
|
25
|
+
*/
|
|
26
|
+
import { FinishReason } from './enums.js';
|
|
27
|
+
/**
|
|
28
|
+
* Finish reasons that mean "no usable content": the installed
|
|
29
|
+
* `@firebase/ai@2.12.0` `badFinishReasons` set, verbatim and in upstream's
|
|
30
|
+
* order. Every one of these makes the response helpers throw instead of
|
|
31
|
+
* returning text, which is exactly the set worth announcing to a developer.
|
|
32
|
+
*/
|
|
33
|
+
const BLOCKING_FINISH_REASONS = [
|
|
34
|
+
FinishReason.RECITATION,
|
|
35
|
+
FinishReason.SAFETY,
|
|
36
|
+
FinishReason.BLOCKLIST,
|
|
37
|
+
FinishReason.PROHIBITED_CONTENT,
|
|
38
|
+
FinishReason.SPII,
|
|
39
|
+
FinishReason.MALFORMED_FUNCTION_CALL,
|
|
40
|
+
FinishReason.IMAGE_SAFETY,
|
|
41
|
+
FinishReason.IMAGE_PROHIBITED_CONTENT,
|
|
42
|
+
FinishReason.IMAGE_OTHER,
|
|
43
|
+
FinishReason.NO_IMAGE,
|
|
44
|
+
FinishReason.IMAGE_RECITATION,
|
|
45
|
+
FinishReason.LANGUAGE,
|
|
46
|
+
FinishReason.UNEXPECTED_TOOL_CALL,
|
|
47
|
+
FinishReason.TOO_MANY_TOOL_CALLS,
|
|
48
|
+
FinishReason.MISSING_THOUGHT_SIGNATURE,
|
|
49
|
+
FinishReason.MALFORMED_RESPONSE,
|
|
50
|
+
];
|
|
51
|
+
/** Does this candidate's finish reason mean the content was withheld? */
|
|
52
|
+
export function isBlockingFinishReason(finishReason) {
|
|
53
|
+
if (!finishReason)
|
|
54
|
+
return false;
|
|
55
|
+
return BLOCKING_FINISH_REASONS.some((reason) => reason === finishReason);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Classify an envelope, mirroring `hasValidCandidates` in
|
|
59
|
+
* `response-helpers.ts` EXACTLY so the event stream and the thrown error can
|
|
60
|
+
* never disagree: candidate 0 with a blocking finish reason is a block; no
|
|
61
|
+
* candidate 0 at all plus any `promptFeedback` is a block; everything else
|
|
62
|
+
* (including a plain `STOP` or `MAX_TOKENS`) is not.
|
|
63
|
+
*
|
|
64
|
+
* Returns `null` when the response is fine, so a caller reads as
|
|
65
|
+
* `const block = describeResponseBlock(res); if (block !== null) …`.
|
|
66
|
+
*/
|
|
67
|
+
export function describeResponseBlock(response) {
|
|
68
|
+
const firstCandidate = response.candidates?.[0];
|
|
69
|
+
if (firstCandidate !== undefined) {
|
|
70
|
+
if (!isBlockingFinishReason(firstCandidate.finishReason))
|
|
71
|
+
return null;
|
|
72
|
+
const candidateBlock = {};
|
|
73
|
+
candidateBlock.finishReason = firstCandidate.finishReason;
|
|
74
|
+
candidateBlock.finishMessage = firstCandidate.finishMessage;
|
|
75
|
+
return candidateBlock;
|
|
76
|
+
}
|
|
77
|
+
if (response.promptFeedback === undefined)
|
|
78
|
+
return null;
|
|
79
|
+
const promptBlock = {};
|
|
80
|
+
promptBlock.blockReason = response.promptFeedback.blockReason;
|
|
81
|
+
return promptBlock;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=blocked.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked.js","sourceRoot":"","sources":["../../src/ai/blocked.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,uBAAuB,GAAsB;IACjD,YAAY,CAAC,UAAU;IACvB,YAAY,CAAC,MAAM;IACnB,YAAY,CAAC,SAAS;IACtB,YAAY,CAAC,kBAAkB;IAC/B,YAAY,CAAC,IAAI;IACjB,YAAY,CAAC,uBAAuB;IACpC,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,wBAAwB;IACrC,YAAY,CAAC,WAAW;IACxB,YAAY,CAAC,QAAQ;IACrB,YAAY,CAAC,gBAAgB;IAC7B,YAAY,CAAC,QAAQ;IACrB,YAAY,CAAC,oBAAoB;IACjC,YAAY,CAAC,mBAAmB;IAChC,YAAY,CAAC,yBAAyB;IACtC,YAAY,CAAC,kBAAkB;CAChC,CAAC;AAEF,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CAAC,YAAgC;IACrE,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAChC,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;AAC3E,CAAC;AAeD;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAsB;IAC1D,MAAM,cAAc,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;QACtE,MAAM,cAAc,GAAkB,EAAE,CAAC;QACzC,cAAc,CAAC,YAAY,GAAG,cAAc,CAAC,YAAY,CAAC;QAC1D,cAAc,CAAC,aAAa,GAAG,cAAc,CAAC,aAAa,CAAC;QAC5D,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,IAAI,QAAQ,CAAC,cAAc,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,WAAW,GAAkB,EAAE,CAAC;IACtC,WAAW,CAAC,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC;IAC9D,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
* - a model-turn functionCall part with no thoughtSignature
|
|
19
19
|
* → `ai-error-fncall-missing-thought-signature`
|
|
20
20
|
*
|
|
21
|
+
* It also announces the refusals production does NOT throw for: a safety /
|
|
22
|
+
* recitation / blocklist block arrives as a 200 with an empty candidate, so
|
|
23
|
+
* the broker lands a `response_blocked` event ({@link emitBlockIfBlocked})
|
|
24
|
+
* alongside the normal op event. Without it a filtered answer is
|
|
25
|
+
* indistinguishable from a model that simply had nothing to say.
|
|
26
|
+
*
|
|
27
|
+
* The same goes for a model SUBSTITUTION ({@link emitModelSubstitution}): an
|
|
28
|
+
* engine that redirects the requested model (an openai `modelMap` entry or
|
|
29
|
+
* catch-all `model`, a gemini experimental alias) answers normally, so
|
|
30
|
+
* nothing anywhere says the developer tested a model they never named.
|
|
31
|
+
*
|
|
21
32
|
* Event emission is best-effort behind one small choke-point ({@link emit}):
|
|
22
33
|
* a throw from the emit path (or any event consumer downstream) must never
|
|
23
34
|
* poison the AI operation the caller just completed — handler errors are the
|
|
@@ -43,6 +54,45 @@ export declare class AiBroker {
|
|
|
43
54
|
private describeEngine;
|
|
44
55
|
/** Additive detail fields every emitted event carries so Studio can show the engine. */
|
|
45
56
|
private engineDetail;
|
|
57
|
+
/**
|
|
58
|
+
* Announce a SAFETY / RECITATION / BLOCKLIST / … block on the event stream.
|
|
59
|
+
*
|
|
60
|
+
* A block is the broker's SILENT refusal: unlike `request_rejected` nothing
|
|
61
|
+
* throws (production answers 200 with an empty candidate), so an app that
|
|
62
|
+
* renders whatever `text()` gave it just shows nothing, and the developer
|
|
63
|
+
* gets no signal anywhere. Emitting at RESPONSE time (not from the response
|
|
64
|
+
* helpers, which only fire if someone reaches for content) means the event
|
|
65
|
+
* lands whether or not the caller ever asks for the text.
|
|
66
|
+
*
|
|
67
|
+
* Detection is `blocked.ts`'s, shared verbatim with the response helpers'
|
|
68
|
+
* throw path, so the stream and the thrown error can never disagree.
|
|
69
|
+
*
|
|
70
|
+
* Returns whether the envelope WAS blocked, so the stream wrapper can
|
|
71
|
+
* announce at most once across its chunks.
|
|
72
|
+
*/
|
|
73
|
+
private emitBlockIfBlocked;
|
|
74
|
+
/**
|
|
75
|
+
* Announce that the engine will answer as a DIFFERENT model than the one
|
|
76
|
+
* requested.
|
|
77
|
+
*
|
|
78
|
+
* A substitution is the quietest failure the broker has: nothing throws,
|
|
79
|
+
* content comes back, and the developer concludes they tested model X when
|
|
80
|
+
* model Y answered (an openai `modelMap` entry or catch-all `model`, a
|
|
81
|
+
* gemini experimental alias). Only engines that actually redirect implement
|
|
82
|
+
* {@link AnswerEngine.resolveEffectiveModel}; the rest are silent by
|
|
83
|
+
* construction.
|
|
84
|
+
*
|
|
85
|
+
* Fired at REQUEST time, before delegating: the swap is a property of the
|
|
86
|
+
* call about to go out, so it lands even when that call then fails.
|
|
87
|
+
* Comparison is bare-vs-bare, since `models/x` to `x` is the wire's prefix
|
|
88
|
+
* convention rather than a substitution, and an exact match emits nothing.
|
|
89
|
+
*
|
|
90
|
+
* `countTokens` is deliberately not announced: the openai engine never
|
|
91
|
+
* sends a model there at all (the count is synthesized locally), so an
|
|
92
|
+
* announcement would name an upstream call that never happens.
|
|
93
|
+
*/
|
|
94
|
+
private emitModelSubstitution;
|
|
95
|
+
private emitRejectionIfBrokerError;
|
|
46
96
|
generateContent(req: GenerateContentRequest, model: string): Promise<WireResponse>;
|
|
47
97
|
/**
|
|
48
98
|
* Chunk objects with the captured framing SEMANTICS (finishReason last
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/ai/broker/broker.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../../src/ai/broker/broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAQ7C,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,sBAAsB,EAEtB,WAAW,EACX,SAAS,EACT,YAAY,EACb,MAAM,YAAY,CAAC;AAuBpB,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC;IACrC,oEAAoE;IACpE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AASD,qBAAa,QAAQ;IACnB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;gBAEvC,OAAO,GAAE,eAAoB;IAsBzC,0EAA0E;IAC1E,OAAO,CAAC,cAAc;IAgBtB,wFAAwF;IACxF,OAAO,CAAC,YAAY;IAgBpB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,qBAAqB;IAmB7B,OAAO,CAAC,0BAA0B;IAS5B,eAAe,CAAC,GAAG,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBxF;;;;;OAKG;IACH,qBAAqB,CAAC,GAAG,EAAE,sBAAsB,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC;IAmCrF,WAAW,CAAC,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAcvF,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,gBAAgB;IAaxB,8EAA8E;IAC9E,OAAO,CAAC,MAAM;IAWd;;;;OAIG;IACH,OAAO,CAAC,IAAI;CAkBb;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,CAYrE"}
|