pinecall 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +134 -0
- package/dist/agent/accepts.d.ts +32 -0
- package/dist/agent/accepts.d.ts.map +1 -0
- package/dist/agent/accepts.js +28 -0
- package/dist/agent/accepts.js.map +1 -0
- package/dist/agent/agent.d.ts +189 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +262 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/authors.d.ts +12 -0
- package/dist/agent/authors.d.ts.map +1 -0
- package/dist/agent/authors.js +28 -0
- package/dist/agent/authors.js.map +1 -0
- package/dist/agent/decorators.d.ts +22 -0
- package/dist/agent/decorators.d.ts.map +1 -0
- package/dist/agent/decorators.js +49 -0
- package/dist/agent/decorators.js.map +1 -0
- package/dist/agent/docstrings.d.ts +43 -0
- package/dist/agent/docstrings.d.ts.map +1 -0
- package/dist/agent/docstrings.js +311 -0
- package/dist/agent/docstrings.js.map +1 -0
- package/dist/agent/lifecycle.d.ts +29 -0
- package/dist/agent/lifecycle.d.ts.map +1 -0
- package/dist/agent/lifecycle.js +11 -0
- package/dist/agent/lifecycle.js.map +1 -0
- package/dist/agent/stages.d.ts +28 -0
- package/dist/agent/stages.d.ts.map +1 -0
- package/dist/agent/stages.js +32 -0
- package/dist/agent/stages.js.map +1 -0
- package/dist/agent/state.d.ts +43 -0
- package/dist/agent/state.d.ts.map +1 -0
- package/dist/agent/state.js +104 -0
- package/dist/agent/state.js.map +1 -0
- package/dist/agent/tools.d.ts +66 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +148 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/agent/visibility.d.ts +40 -0
- package/dist/agent/visibility.d.ts.map +1 -0
- package/dist/agent/visibility.js +89 -0
- package/dist/agent/visibility.js.map +1 -0
- package/dist/call/call.d.ts +55 -0
- package/dist/call/call.d.ts.map +1 -0
- package/dist/call/call.js +108 -0
- package/dist/call/call.js.map +1 -0
- package/dist/call/history.d.ts +34 -0
- package/dist/call/history.d.ts.map +1 -0
- package/dist/call/history.js +38 -0
- package/dist/call/history.js.map +1 -0
- package/dist/call/room.d.ts +58 -0
- package/dist/call/room.d.ts.map +1 -0
- package/dist/call/room.js +68 -0
- package/dist/call/room.js.map +1 -0
- package/dist/cli/browser.d.ts +8 -0
- package/dist/cli/browser.d.ts.map +1 -0
- package/dist/cli/browser.js +27 -0
- package/dist/cli/browser.js.map +1 -0
- package/dist/cli/callbacks.d.ts +26 -0
- package/dist/cli/callbacks.d.ts.map +1 -0
- package/dist/cli/callbacks.js +68 -0
- package/dist/cli/callbacks.js.map +1 -0
- package/dist/cli/chat.d.ts +21 -0
- package/dist/cli/chat.d.ts.map +1 -0
- package/dist/cli/chat.js +214 -0
- package/dist/cli/chat.js.map +1 -0
- package/dist/cli/config.d.ts +16 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +94 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/connected.d.ts +30 -0
- package/dist/cli/connected.d.ts.map +1 -0
- package/dist/cli/connected.js +32 -0
- package/dist/cli/connected.js.map +1 -0
- package/dist/cli/credentials.d.ts +41 -0
- package/dist/cli/credentials.d.ts.map +1 -0
- package/dist/cli/credentials.js +98 -0
- package/dist/cli/credentials.js.map +1 -0
- package/dist/cli/ear.d.ts +3 -0
- package/dist/cli/ear.d.ts.map +1 -0
- package/dist/cli/ear.js +59 -0
- package/dist/cli/ear.js.map +1 -0
- package/dist/cli/env.d.ts +40 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +45 -0
- package/dist/cli/env.js.map +1 -0
- package/dist/cli/eval.d.ts +37 -0
- package/dist/cli/eval.d.ts.map +1 -0
- package/dist/cli/eval.js +83 -0
- package/dist/cli/eval.js.map +1 -0
- package/dist/cli/groups.d.ts +17 -0
- package/dist/cli/groups.d.ts.map +1 -0
- package/dist/cli/groups.js +38 -0
- package/dist/cli/groups.js.map +1 -0
- package/dist/cli/index.d.ts +16 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +169 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/keys.d.ts +28 -0
- package/dist/cli/keys.d.ts.map +1 -0
- package/dist/cli/keys.js +137 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/knowledge.d.ts +35 -0
- package/dist/cli/knowledge.d.ts.map +1 -0
- package/dist/cli/knowledge.js +174 -0
- package/dist/cli/knowledge.js.map +1 -0
- package/dist/cli/line.d.ts +33 -0
- package/dist/cli/line.d.ts.map +1 -0
- package/dist/cli/line.js +134 -0
- package/dist/cli/line.js.map +1 -0
- package/dist/cli/listening.d.ts +38 -0
- package/dist/cli/listening.d.ts.map +1 -0
- package/dist/cli/listening.js +124 -0
- package/dist/cli/listening.js.map +1 -0
- package/dist/cli/load.d.ts +38 -0
- package/dist/cli/load.d.ts.map +1 -0
- package/dist/cli/load.js +99 -0
- package/dist/cli/load.js.map +1 -0
- package/dist/cli/login.d.ts +30 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +158 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/machine.d.ts +8 -0
- package/dist/cli/machine.d.ts.map +1 -0
- package/dist/cli/machine.js +41 -0
- package/dist/cli/machine.js.map +1 -0
- package/dist/cli/memory.d.ts +26 -0
- package/dist/cli/memory.d.ts.map +1 -0
- package/dist/cli/memory.js +148 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/numbers.d.ts +25 -0
- package/dist/cli/numbers.d.ts.map +1 -0
- package/dist/cli/numbers.js +132 -0
- package/dist/cli/numbers.js.map +1 -0
- package/dist/cli/personas.d.ts +5 -0
- package/dist/cli/personas.d.ts.map +1 -0
- package/dist/cli/personas.js +94 -0
- package/dist/cli/personas.js.map +1 -0
- package/dist/cli/pipeline.d.ts +52 -0
- package/dist/cli/pipeline.d.ts.map +1 -0
- package/dist/cli/pipeline.js +184 -0
- package/dist/cli/pipeline.js.map +1 -0
- package/dist/cli/profiles.d.ts +70 -0
- package/dist/cli/profiles.d.ts.map +1 -0
- package/dist/cli/profiles.js +210 -0
- package/dist/cli/profiles.js.map +1 -0
- package/dist/cli/prompt.d.ts +20 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +58 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/cli/providers.d.ts +14 -0
- package/dist/cli/providers.d.ts.map +1 -0
- package/dist/cli/providers.js +116 -0
- package/dist/cli/providers.js.map +1 -0
- package/dist/cli/remember.d.ts +29 -0
- package/dist/cli/remember.d.ts.map +1 -0
- package/dist/cli/remember.js +112 -0
- package/dist/cli/remember.js.map +1 -0
- package/dist/cli/run.d.ts +20 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +347 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/runs/candidate.d.ts +51 -0
- package/dist/cli/runs/candidate.d.ts.map +1 -0
- package/dist/cli/runs/candidate.js +127 -0
- package/dist/cli/runs/candidate.js.map +1 -0
- package/dist/cli/runs/drift.d.ts +75 -0
- package/dist/cli/runs/drift.d.ts.map +1 -0
- package/dist/cli/runs/drift.js +151 -0
- package/dist/cli/runs/drift.js.map +1 -0
- package/dist/cli/runs/index.d.ts +5 -0
- package/dist/cli/runs/index.d.ts.map +1 -0
- package/dist/cli/runs/index.js +99 -0
- package/dist/cli/runs/index.js.map +1 -0
- package/dist/cli/runs/suites.d.ts +16 -0
- package/dist/cli/runs/suites.d.ts.map +1 -0
- package/dist/cli/runs/suites.js +63 -0
- package/dist/cli/runs/suites.js.map +1 -0
- package/dist/cli/secret.d.ts +18 -0
- package/dist/cli/secret.d.ts.map +1 -0
- package/dist/cli/secret.js +41 -0
- package/dist/cli/secret.js.map +1 -0
- package/dist/cli/sessions.d.ts +21 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +174 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/signup.d.ts +25 -0
- package/dist/cli/signup.d.ts.map +1 -0
- package/dist/cli/signup.js +122 -0
- package/dist/cli/signup.js.map +1 -0
- package/dist/cli/simulate.d.ts +45 -0
- package/dist/cli/simulate.d.ts.map +1 -0
- package/dist/cli/simulate.js +320 -0
- package/dist/cli/simulate.js.map +1 -0
- package/dist/cli/supervise.d.ts +18 -0
- package/dist/cli/supervise.d.ts.map +1 -0
- package/dist/cli/supervise.js +134 -0
- package/dist/cli/supervise.js.map +1 -0
- package/dist/cli/test.d.ts +12 -0
- package/dist/cli/test.d.ts.map +1 -0
- package/dist/cli/test.js +128 -0
- package/dist/cli/test.js.map +1 -0
- package/dist/cli/testing/caller.d.ts +28 -0
- package/dist/cli/testing/caller.d.ts.map +1 -0
- package/dist/cli/testing/caller.js +30 -0
- package/dist/cli/testing/caller.js.map +1 -0
- package/dist/cli/testing/gateway.d.ts +172 -0
- package/dist/cli/testing/gateway.d.ts.map +1 -0
- package/dist/cli/testing/gateway.js +96 -0
- package/dist/cli/testing/gateway.js.map +1 -0
- package/dist/cli/testing/goldens.d.ts +61 -0
- package/dist/cli/testing/goldens.d.ts.map +1 -0
- package/dist/cli/testing/goldens.js +54 -0
- package/dist/cli/testing/goldens.js.map +1 -0
- package/dist/cli/testing/latency.d.ts +15 -0
- package/dist/cli/testing/latency.d.ts.map +1 -0
- package/dist/cli/testing/latency.js +44 -0
- package/dist/cli/testing/latency.js.map +1 -0
- package/dist/cli/testing/matrix.d.ts +12 -0
- package/dist/cli/testing/matrix.d.ts.map +1 -0
- package/dist/cli/testing/matrix.js +103 -0
- package/dist/cli/testing/matrix.js.map +1 -0
- package/dist/cli/testing/progress.d.ts +26 -0
- package/dist/cli/testing/progress.d.ts.map +1 -0
- package/dist/cli/testing/progress.js +185 -0
- package/dist/cli/testing/progress.js.map +1 -0
- package/dist/cli/testing/reproduction.d.ts +19 -0
- package/dist/cli/testing/reproduction.d.ts.map +1 -0
- package/dist/cli/testing/reproduction.js +65 -0
- package/dist/cli/testing/reproduction.js.map +1 -0
- package/dist/cli/testing/score.d.ts +11 -0
- package/dist/cli/testing/score.d.ts.map +1 -0
- package/dist/cli/testing/score.js +54 -0
- package/dist/cli/testing/score.js.map +1 -0
- package/dist/cli/testing/seeding.d.ts +32 -0
- package/dist/cli/testing/seeding.d.ts.map +1 -0
- package/dist/cli/testing/seeding.js +44 -0
- package/dist/cli/testing/seeding.js.map +1 -0
- package/dist/cli/testing/suite.d.ts +40 -0
- package/dist/cli/testing/suite.d.ts.map +1 -0
- package/dist/cli/testing/suite.js +103 -0
- package/dist/cli/testing/suite.js.map +1 -0
- package/dist/cli/testing/voice.d.ts +37 -0
- package/dist/cli/testing/voice.d.ts.map +1 -0
- package/dist/cli/testing/voice.js +53 -0
- package/dist/cli/testing/voice.js.map +1 -0
- package/dist/cli/ui/admin/assets/index-C3WMXdfL.css +1 -0
- package/dist/cli/ui/admin/assets/index-DR1mxoAh.js +58 -0
- package/dist/cli/ui/admin/index.html +20 -0
- package/dist/cli/ui/asked.d.ts +16 -0
- package/dist/cli/ui/asked.d.ts.map +1 -0
- package/dist/cli/ui/asked.js +53 -0
- package/dist/cli/ui/asked.js.map +1 -0
- package/dist/cli/ui/browser.d.ts +10 -0
- package/dist/cli/ui/browser.d.ts.map +1 -0
- package/dist/cli/ui/browser.js +30 -0
- package/dist/cli/ui/browser.js.map +1 -0
- package/dist/cli/ui/chatting.d.ts +62 -0
- package/dist/cli/ui/chatting.d.ts.map +1 -0
- package/dist/cli/ui/chatting.js +171 -0
- package/dist/cli/ui/chatting.js.map +1 -0
- package/dist/cli/ui/console/assets/index-DCTnou52.css +1 -0
- package/dist/cli/ui/console/assets/index-dOcE4usU.js +99 -0
- package/dist/cli/ui/console/index.html +20 -0
- package/dist/cli/ui/console/logo-mark.png +0 -0
- package/dist/cli/ui/doors.d.ts +37 -0
- package/dist/cli/ui/doors.d.ts.map +1 -0
- package/dist/cli/ui/doors.js +70 -0
- package/dist/cli/ui/doors.js.map +1 -0
- package/dist/cli/ui/drifting.d.ts +23 -0
- package/dist/cli/ui/drifting.d.ts.map +1 -0
- package/dist/cli/ui/drifting.js +33 -0
- package/dist/cli/ui/drifting.js.map +1 -0
- package/dist/cli/ui/index.d.ts +15 -0
- package/dist/cli/ui/index.d.ts.map +1 -0
- package/dist/cli/ui/index.js +117 -0
- package/dist/cli/ui/index.js.map +1 -0
- package/dist/cli/ui/knowing.d.ts +36 -0
- package/dist/cli/ui/knowing.d.ts.map +1 -0
- package/dist/cli/ui/knowing.js +86 -0
- package/dist/cli/ui/knowing.js.map +1 -0
- package/dist/cli/ui/promoting.d.ts +26 -0
- package/dist/cli/ui/promoting.d.ts.map +1 -0
- package/dist/cli/ui/promoting.js +44 -0
- package/dist/cli/ui/promoting.js.map +1 -0
- package/dist/cli/ui/refusal.d.ts +18 -0
- package/dist/cli/ui/refusal.d.ts.map +1 -0
- package/dist/cli/ui/refusal.js +26 -0
- package/dist/cli/ui/refusal.js.map +1 -0
- package/dist/cli/ui/refused.d.ts +8 -0
- package/dist/cli/ui/refused.d.ts.map +1 -0
- package/dist/cli/ui/refused.js +11 -0
- package/dist/cli/ui/refused.js.map +1 -0
- package/dist/cli/ui/remembering.d.ts +38 -0
- package/dist/cli/ui/remembering.d.ts.map +1 -0
- package/dist/cli/ui/remembering.js +87 -0
- package/dist/cli/ui/remembering.js.map +1 -0
- package/dist/cli/ui/reproducing.d.ts +23 -0
- package/dist/cli/ui/reproducing.d.ts.map +1 -0
- package/dist/cli/ui/reproducing.js +52 -0
- package/dist/cli/ui/reproducing.js.map +1 -0
- package/dist/cli/ui/server.d.ts +22 -0
- package/dist/cli/ui/server.d.ts.map +1 -0
- package/dist/cli/ui/server.js +211 -0
- package/dist/cli/ui/server.js.map +1 -0
- package/dist/cli/ui/simulating.d.ts +47 -0
- package/dist/cli/ui/simulating.d.ts.map +1 -0
- package/dist/cli/ui/simulating.js +86 -0
- package/dist/cli/ui/simulating.js.map +1 -0
- package/dist/cli/ui/testing.d.ts +49 -0
- package/dist/cli/ui/testing.d.ts.map +1 -0
- package/dist/cli/ui/testing.js +104 -0
- package/dist/cli/ui/testing.js.map +1 -0
- package/dist/cli/view.d.ts +43 -0
- package/dist/cli/view.d.ts.map +1 -0
- package/dist/cli/view.js +137 -0
- package/dist/cli/view.js.map +1 -0
- package/dist/cli/whoami.d.ts +37 -0
- package/dist/cli/whoami.d.ts.map +1 -0
- package/dist/cli/whoami.js +78 -0
- package/dist/cli/whoami.js.map +1 -0
- package/dist/cli/world.d.ts +33 -0
- package/dist/cli/world.d.ts.map +1 -0
- package/dist/cli/world.js +48 -0
- package/dist/cli/world.js.map +1 -0
- package/dist/client/agent.d.ts +87 -0
- package/dist/client/agent.d.ts.map +1 -0
- package/dist/client/agent.js +209 -0
- package/dist/client/agent.js.map +1 -0
- package/dist/client/calls.d.ts +77 -0
- package/dist/client/calls.d.ts.map +1 -0
- package/dist/client/calls.js +153 -0
- package/dist/client/calls.js.map +1 -0
- package/dist/client/client.d.ts +58 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +146 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/connection.d.ts +47 -0
- package/dist/client/connection.d.ts.map +1 -0
- package/dist/client/connection.js +141 -0
- package/dist/client/connection.js.map +1 -0
- package/dist/client/endpoints.d.ts +7 -0
- package/dist/client/endpoints.d.ts.map +1 -0
- package/dist/client/endpoints.js +21 -0
- package/dist/client/endpoints.js.map +1 -0
- package/dist/client/frames.d.ts +24 -0
- package/dist/client/frames.d.ts.map +1 -0
- package/dist/client/frames.js +49 -0
- package/dist/client/frames.js.map +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +14 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/listeners.d.ts +36 -0
- package/dist/client/listeners.d.ts.map +1 -0
- package/dist/client/listeners.js +61 -0
- package/dist/client/listeners.js.map +1 -0
- package/dist/client/observe.d.ts +44 -0
- package/dist/client/observe.d.ts.map +1 -0
- package/dist/client/observe.js +122 -0
- package/dist/client/observe.js.map +1 -0
- package/dist/client/testing/gateway.d.ts +39 -0
- package/dist/client/testing/gateway.d.ts.map +1 -0
- package/dist/client/testing/gateway.js +129 -0
- package/dist/client/testing/gateway.js.map +1 -0
- package/dist/client/testing/index.d.ts +4 -0
- package/dist/client/testing/index.d.ts.map +1 -0
- package/dist/client/testing/index.js +4 -0
- package/dist/client/testing/index.js.map +1 -0
- package/dist/client/testing/log.d.ts +26 -0
- package/dist/client/testing/log.d.ts.map +1 -0
- package/dist/client/testing/log.js +111 -0
- package/dist/client/testing/log.js.map +1 -0
- package/dist/client/testing/loopback.d.ts +3 -0
- package/dist/client/testing/loopback.d.ts.map +1 -0
- package/dist/client/testing/loopback.js +3 -0
- package/dist/client/testing/loopback.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/channels.d.ts +16 -0
- package/dist/runtime/channels.d.ts.map +1 -0
- package/dist/runtime/channels.js +30 -0
- package/dist/runtime/channels.js.map +1 -0
- package/dist/runtime/connect.d.ts +51 -0
- package/dist/runtime/connect.d.ts.map +1 -0
- package/dist/runtime/connect.js +284 -0
- package/dist/runtime/connect.js.map +1 -0
- package/dist/runtime/dispatch.d.ts +37 -0
- package/dist/runtime/dispatch.d.ts.map +1 -0
- package/dist/runtime/dispatch.js +52 -0
- package/dist/runtime/dispatch.js.map +1 -0
- package/dist/runtime/grounding.d.ts +15 -0
- package/dist/runtime/grounding.d.ts.map +1 -0
- package/dist/runtime/grounding.js +72 -0
- package/dist/runtime/grounding.js.map +1 -0
- package/dist/runtime/recall.d.ts +10 -0
- package/dist/runtime/recall.d.ts.map +1 -0
- package/dist/runtime/recall.js +13 -0
- package/dist/runtime/recall.js.map +1 -0
- package/dist/runtime/run-tool.d.ts +26 -0
- package/dist/runtime/run-tool.d.ts.map +1 -0
- package/dist/runtime/run-tool.js +82 -0
- package/dist/runtime/run-tool.js.map +1 -0
- package/dist/views/components.d.ts +17 -0
- package/dist/views/components.d.ts.map +1 -0
- package/dist/views/components.js +33 -0
- package/dist/views/components.js.map +1 -0
- package/dist/views/jsx-dev-runtime.d.ts +3 -0
- package/dist/views/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/views/jsx-dev-runtime.js +5 -0
- package/dist/views/jsx-dev-runtime.js.map +1 -0
- package/dist/views/jsx-runtime.d.ts +49 -0
- package/dist/views/jsx-runtime.d.ts.map +1 -0
- package/dist/views/jsx-runtime.js +67 -0
- package/dist/views/jsx-runtime.js.map +1 -0
- package/dist/views/lang.d.ts +17 -0
- package/dist/views/lang.d.ts.map +1 -0
- package/dist/views/lang.js +46 -0
- package/dist/views/lang.js.map +1 -0
- package/dist/views/layout.d.ts +19 -0
- package/dist/views/layout.d.ts.map +1 -0
- package/dist/views/layout.js +62 -0
- package/dist/views/layout.js.map +1 -0
- package/dist/views/render.d.ts +19 -0
- package/dist/views/render.d.ts.map +1 -0
- package/dist/views/render.js +26 -0
- package/dist/views/render.js.map +1 -0
- package/package.json +76 -0
- package/tsconfig.tenant.json +24 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Which golden's state a starting call opens in, and the check that it was the right one. */
|
|
2
|
+
/** What to say when the calls did not arrive in the order the run says it opened them in. */
|
|
3
|
+
export const OUT_OF_ORDER = "the calls did not arrive in the order the run opened them: {said} took the state of {seeded}";
|
|
4
|
+
/**
|
|
5
|
+
* The states a run is about to open, handed out as its calls start.
|
|
6
|
+
*
|
|
7
|
+
* The seed cannot come off the log: `session.configure {state}` writes `state.changed` into the
|
|
8
|
+
* call and stops there — the tenant's class is another process and nothing on the wire moves it —
|
|
9
|
+
* and by the time that entry reaches this terminal the bridge is re-rendering on every field, so
|
|
10
|
+
* restoring three fields would show the model two states the call was never in. `mount`'s own
|
|
11
|
+
* `opening` seam is the moment between `onCall` and the first render, and this is what fills it.
|
|
12
|
+
*
|
|
13
|
+
* Which state belongs to which call is the runner's order: one run at a time (a second is refused
|
|
14
|
+
* with 409) and one conversation at a time inside it, models outermost. `mismatched` checks that
|
|
15
|
+
* afterwards against what the run says it opened, so a wrong seed is a loud line and never a
|
|
16
|
+
* golden that quietly tested something else.
|
|
17
|
+
*/
|
|
18
|
+
export class Openings {
|
|
19
|
+
waiting = [];
|
|
20
|
+
seeded = [];
|
|
21
|
+
/** The goldens this run will open, once per model, in the order the runner will walk them. */
|
|
22
|
+
expects(goldens, models) {
|
|
23
|
+
this.waiting = Array.from({ length: Math.max(models, 1) }, () => goldens).flat();
|
|
24
|
+
this.seeded.length = 0;
|
|
25
|
+
}
|
|
26
|
+
/** The state this starting call opens in: the next golden's, or none when no run opened it. */
|
|
27
|
+
opening(call) {
|
|
28
|
+
if (call.run === null)
|
|
29
|
+
return undefined;
|
|
30
|
+
const golden = this.waiting.shift();
|
|
31
|
+
if (golden === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
this.seeded.push(golden.name);
|
|
34
|
+
return golden.state;
|
|
35
|
+
}
|
|
36
|
+
/** The sentence to print when a call took a state that was not its golden's, or nothing. */
|
|
37
|
+
mismatched(run) {
|
|
38
|
+
const wrong = run.calls.findIndex((opened, index) => opened.golden !== this.seeded[index]);
|
|
39
|
+
if (wrong === -1)
|
|
40
|
+
return undefined;
|
|
41
|
+
return OUT_OF_ORDER.replace("{said}", run.calls[wrong].golden).replace("{seeded}", this.seeded[wrong] ?? "no golden at all");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=seeding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeding.js","sourceRoot":"","sources":["../../../src/cli/testing/seeding.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAQ9F,6FAA6F;AAC7F,MAAM,CAAC,MAAM,YAAY,GACvB,8FAA8F,CAAC;AAEjG;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,QAAQ;IACX,OAAO,GAAa,EAAE,CAAC;IACd,MAAM,GAAa,EAAE,CAAC;IAEvC,8FAA8F;IAC9F,OAAO,CAAC,OAAiB,EAAE,MAAc;QACvC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,+FAA+F;IAC/F,OAAO,CAAC,IAAa;QACnB,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,4FAA4F;IAC5F,UAAU,CAAC,GAAY;QACrB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3F,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QACnC,OAAO,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CACrE,UAAU,EACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,kBAAkB,CACzC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** One suite run through the class mounted in this process: written once, for the terminal verb and the console. */
|
|
2
|
+
import type { Camel, ModelConfig } from "@pinecall/protocol";
|
|
3
|
+
import type { Pinecall } from "../../client/index.js";
|
|
4
|
+
import { type Mounted } from "../../runtime/connect.js";
|
|
5
|
+
import { type Loaded } from "../load.js";
|
|
6
|
+
import { type Door, type Wanted } from "./gateway.js";
|
|
7
|
+
import type { Golden } from "./goldens.js";
|
|
8
|
+
import { Openings } from "./seeding.js";
|
|
9
|
+
/** The class, mounted for a suite, and the openings that hand each call its golden's state. */
|
|
10
|
+
export interface ForASuite {
|
|
11
|
+
mounted: Mounted;
|
|
12
|
+
openings: Openings;
|
|
13
|
+
}
|
|
14
|
+
/** One suite: which goldens, under which models, on what line, printed where. */
|
|
15
|
+
export interface Suite {
|
|
16
|
+
door: Door;
|
|
17
|
+
loaded: Loaded;
|
|
18
|
+
held: ForASuite;
|
|
19
|
+
goldens: Golden[];
|
|
20
|
+
models: Camel<ModelConfig>[];
|
|
21
|
+
/** Ring 2's three fields, when the suite is spoken; nothing at all when it is written. */
|
|
22
|
+
line: Partial<Wanted>;
|
|
23
|
+
out: NodeJS.WritableStream;
|
|
24
|
+
json: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The class mounted for a suite: `takesUnclaimed: false` for the reason `chat` has it — this
|
|
28
|
+
* process holds the agent so that the run reaches THIS class, and a real phone call must not ring
|
|
29
|
+
* in a terminal running a suite. Every golden opens its call in its own state, handed to the
|
|
30
|
+
* instance through mount's own `opening` seam — the moment between the class's onCall and the
|
|
31
|
+
* first render.
|
|
32
|
+
*/
|
|
33
|
+
export declare function mountedForASuite(loaded: Loaded, pc: Pinecall): ForASuite;
|
|
34
|
+
/**
|
|
35
|
+
* The suite, run and reported: the run asked of the gateway, followed while it happens, the seeds
|
|
36
|
+
* checked against what it opened, every broken golden written out, and the exit code a gate reads.
|
|
37
|
+
* 1 when a golden did not hold or the gateway was busy, whatever else went right.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ranSuite(suite: Suite): Promise<number>;
|
|
40
|
+
//# sourceMappingURL=suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suite.d.ts","sourceRoot":"","sources":["../../../src/cli/testing/suite.ts"],"names":[],"mappings":"AAAA,oHAAoH;AAEpH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EAAS,KAAK,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,YAAY,CAAC;AACvD,OAAO,EAAqC,KAAK,IAAI,EAA4B,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AACnH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAK3C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAMxC,+FAA+F;AAC/F,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;IAC7B,0FAA0F;IAC1F,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC;IAC3B,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,SAAS,CAQxE;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B5D"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/** One suite run through the class mounted in this process: written once, for the terminal verb and the console. */
|
|
2
|
+
import { mount } from "../../runtime/connect.js";
|
|
3
|
+
import { mountOptions } from "../load.js";
|
|
4
|
+
import { aRun, entriesOf, Refused, theRuns } from "./gateway.js";
|
|
5
|
+
import { mediansOf } from "./latency.js";
|
|
6
|
+
import { reportOf } from "./matrix.js";
|
|
7
|
+
import { followed } from "./progress.js";
|
|
8
|
+
import { whereTheyAre, writtenOut } from "./reproduction.js";
|
|
9
|
+
import { Openings } from "./seeding.js";
|
|
10
|
+
// The gateway runs one suite at a time and says so with a 409. Its own sentence is about the
|
|
11
|
+
// runner; this one is about what the person types next.
|
|
12
|
+
const BUSY = "a run is already going on {agent} ({id}) — pinecall runs show {id} to watch it";
|
|
13
|
+
/**
|
|
14
|
+
* The class mounted for a suite: `takesUnclaimed: false` for the reason `chat` has it — this
|
|
15
|
+
* process holds the agent so that the run reaches THIS class, and a real phone call must not ring
|
|
16
|
+
* in a terminal running a suite. Every golden opens its call in its own state, handed to the
|
|
17
|
+
* instance through mount's own `opening` seam — the moment between the class's onCall and the
|
|
18
|
+
* first render.
|
|
19
|
+
*/
|
|
20
|
+
export function mountedForASuite(loaded, pc) {
|
|
21
|
+
const openings = new Openings();
|
|
22
|
+
const mounted = mount(loaded.ctor, {
|
|
23
|
+
...mountOptions(loaded, pc),
|
|
24
|
+
takesUnclaimed: false,
|
|
25
|
+
opening: (call) => openings.opening(call),
|
|
26
|
+
});
|
|
27
|
+
return { mounted, openings };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The suite, run and reported: the run asked of the gateway, followed while it happens, the seeds
|
|
31
|
+
* checked against what it opened, every broken golden written out, and the exit code a gate reads.
|
|
32
|
+
* 1 when a golden did not hold or the gateway was busy, whatever else went right.
|
|
33
|
+
*/
|
|
34
|
+
export async function ranSuite(suite) {
|
|
35
|
+
const { door, held, goldens, models, out } = suite;
|
|
36
|
+
held.openings.expects(goldens, models.length);
|
|
37
|
+
const declaredAs = declaredBy(suite.loaded.ctor);
|
|
38
|
+
const pending = aRun(door, {
|
|
39
|
+
agent: held.mounted.slug,
|
|
40
|
+
goldens,
|
|
41
|
+
...(models.length > 0 ? { models } : {}),
|
|
42
|
+
...(held.mounted.agent.app === undefined ? {} : { app: held.mounted.agent.app }),
|
|
43
|
+
...suite.line,
|
|
44
|
+
});
|
|
45
|
+
const watched = {
|
|
46
|
+
agent: held.mounted.slug,
|
|
47
|
+
goldens: goldens.length,
|
|
48
|
+
models: models.length > 0 ? models.map((model) => `${model.provider}/${model.model}`) : [declaredAs],
|
|
49
|
+
declaredAs,
|
|
50
|
+
};
|
|
51
|
+
let run;
|
|
52
|
+
try {
|
|
53
|
+
run = await followed(door, watched, pending, out, suite.json);
|
|
54
|
+
}
|
|
55
|
+
catch (refused) {
|
|
56
|
+
if (!(refused instanceof Refused) || refused.status !== 409)
|
|
57
|
+
throw refused;
|
|
58
|
+
process.stderr.write(`${await busy(door, held.mounted.slug, refused)}\n`);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
const wrong = held.openings.mismatched(run);
|
|
62
|
+
if (wrong !== undefined)
|
|
63
|
+
process.stderr.write(`${wrong}\n`);
|
|
64
|
+
return await reported(door, run, goldens, declaredAs, suite.json, out);
|
|
65
|
+
}
|
|
66
|
+
/** The run printed and answered for: exit 1 when a golden did not hold, whatever else went right. */
|
|
67
|
+
async function reported(door, run, goldens, declaredAs, asJson, out) {
|
|
68
|
+
const logs = await logsOf(door, run);
|
|
69
|
+
const latencies = {};
|
|
70
|
+
for (const [call, entries] of Object.entries(logs))
|
|
71
|
+
latencies[call] = mediansOf(entries);
|
|
72
|
+
// The logs are already in hand, so a broken golden costs one write and no second round trip.
|
|
73
|
+
const written = writtenOut(run, goldens, logs);
|
|
74
|
+
if (asJson)
|
|
75
|
+
out.write(`${JSON.stringify({ run, latencies, reproductions: written })}\n`);
|
|
76
|
+
else
|
|
77
|
+
out.write(`${[...reportOf(run, latencies, declaredAs), ...whereTheyAre(written)].join("\n")}\n`);
|
|
78
|
+
return run.status === "done" && (run.matrix?.failures.length ?? 0) === 0 ? 0 : 1;
|
|
79
|
+
}
|
|
80
|
+
// Each call's own log, by call id. The runner's matrix carries what the graphs answered and
|
|
81
|
+
// `call.summary`; the per-turn metrics entries and every other thing that happened live in the
|
|
82
|
+
// log, so the report reads them from there rather than asking anybody to summarise them twice.
|
|
83
|
+
async function logsOf(door, run) {
|
|
84
|
+
const logs = {};
|
|
85
|
+
for (const opened of run.calls)
|
|
86
|
+
logs[opened.call] = await entriesOf(door, opened.call);
|
|
87
|
+
return logs;
|
|
88
|
+
}
|
|
89
|
+
// Which run has the AGENT is read off the door that lists them rather than out of the refusal's
|
|
90
|
+
// sentence: the runner holds one run per agent, so the newest running run of THIS agent is the
|
|
91
|
+
// one holding it — the org's newest run may well be somebody else's agent.
|
|
92
|
+
async function busy(door, agent, refused) {
|
|
93
|
+
const newest = (await theRuns(door, 1, agent))[0];
|
|
94
|
+
if (newest?.status !== "running")
|
|
95
|
+
return refused.message;
|
|
96
|
+
return BUSY.replaceAll("{id}", newest.id).replace("{agent}", agent);
|
|
97
|
+
}
|
|
98
|
+
/** The model a person recognises: the word the class itself wrote, `llm = "haiku"` and no table. */
|
|
99
|
+
function declaredBy(ctor) {
|
|
100
|
+
const declared = new ctor().llm;
|
|
101
|
+
return typeof declared === "string" && declared !== "" ? declared : "the app's own model";
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=suite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suite.js","sourceRoot":"","sources":["../../../src/cli/testing/suite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** The spoken door of a simulation: the call is held in the runtime, and watched from here. */
|
|
2
|
+
import type { Door, Entry, Persona } from "./gateway.js";
|
|
3
|
+
/** How the caller's line is spoiled on purpose. Absent from a run means a clean line. */
|
|
4
|
+
export interface Degraded {
|
|
5
|
+
/** How many dB under the caller's own voice the interferer sits. */
|
|
6
|
+
interferer_db: number;
|
|
7
|
+
/** The share of the caller's packets that never arrive, 0 to 1. */
|
|
8
|
+
packet_loss: number;
|
|
9
|
+
}
|
|
10
|
+
export declare const DEGRADED: Degraded;
|
|
11
|
+
/** What the runtime says about a spoken call once it is over: what was said, and on what line. */
|
|
12
|
+
export interface Called {
|
|
13
|
+
call: string;
|
|
14
|
+
turns: number;
|
|
15
|
+
line: string;
|
|
16
|
+
}
|
|
17
|
+
/** A call id, minted here: a room's name IS the call, so the terminal can watch its log at once. */
|
|
18
|
+
export declare function aCallId(): string;
|
|
19
|
+
/**
|
|
20
|
+
* One spoken call, held in the runtime because everything it needs is there — the LiveKit pair
|
|
21
|
+
* that signs the caller's seat, the provider key the persona is played with, and the box's own
|
|
22
|
+
* speech tool. This side mints the id and watches the log; nothing here opens an audio device.
|
|
23
|
+
*/
|
|
24
|
+
export declare function aVoiceCall(door: Door, wanted: {
|
|
25
|
+
call: string;
|
|
26
|
+
agent: string;
|
|
27
|
+
persona: Persona;
|
|
28
|
+
turns: number;
|
|
29
|
+
degraded?: Degraded;
|
|
30
|
+
}): Promise<Called>;
|
|
31
|
+
/**
|
|
32
|
+
* The call's log as it is written, polled from a cursor: the terminal prints both sides of a
|
|
33
|
+
* spoken call while it happens, and every entry it prints is the log's own — never a second copy
|
|
34
|
+
* this process kept. It stops when `over` settles, which is when the runtime hung the call up.
|
|
35
|
+
*/
|
|
36
|
+
export declare function watching(door: Door, call: string, over: Promise<unknown>, absorb: (entry: Entry) => void, every?: number): Promise<void>;
|
|
37
|
+
//# sourceMappingURL=voice.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/cli/testing/voice.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAI/F,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD,yFAAyF;AACzF,MAAM,WAAW,QAAQ;IACvB,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAKD,eAAO,MAAM,QAAQ,EAAE,QAAgD,CAAC;AAExE,kGAAkG;AAClG,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oGAAoG;AACpG,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAC5F,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,EACtB,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAC9B,KAAK,SAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** The spoken door of a simulation: the call is held in the runtime, and watched from here. */
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { asked, entriesOf } from "./gateway.js";
|
|
4
|
+
// A television behind the caller, at the level the five calls that measured this were run from:
|
|
5
|
+
// 15 dB under them was already enough for two of its sentences to become `turn.user`. The
|
|
6
|
+
// measurement is in the runtime's docs/decisions/voice-bridge.md.
|
|
7
|
+
export const DEGRADED = { interferer_db: 15, packet_loss: 0 };
|
|
8
|
+
/** A call id, minted here: a room's name IS the call, so the terminal can watch its log at once. */
|
|
9
|
+
export function aCallId() {
|
|
10
|
+
return `call_${randomBytes(12).toString("hex")}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* One spoken call, held in the runtime because everything it needs is there — the LiveKit pair
|
|
14
|
+
* that signs the caller's seat, the provider key the persona is played with, and the box's own
|
|
15
|
+
* speech tool. This side mints the id and watches the log; nothing here opens an audio device.
|
|
16
|
+
*/
|
|
17
|
+
export async function aVoiceCall(door, wanted) {
|
|
18
|
+
return await asked(door, "/v1/evals/voice", {
|
|
19
|
+
method: "POST",
|
|
20
|
+
body: {
|
|
21
|
+
call: wanted.call,
|
|
22
|
+
agent: wanted.agent,
|
|
23
|
+
persona: wanted.persona,
|
|
24
|
+
turns: wanted.turns,
|
|
25
|
+
...(wanted.degraded ?? {}),
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The call's log as it is written, polled from a cursor: the terminal prints both sides of a
|
|
31
|
+
* spoken call while it happens, and every entry it prints is the log's own — never a second copy
|
|
32
|
+
* this process kept. It stops when `over` settles, which is when the runtime hung the call up.
|
|
33
|
+
*/
|
|
34
|
+
export async function watching(door, call, over, absorb, every = 400) {
|
|
35
|
+
let running = true;
|
|
36
|
+
// The refusal is answered for by whoever awaited the call itself; here it is only the end of it.
|
|
37
|
+
void over.catch(() => undefined).finally(() => (running = false));
|
|
38
|
+
let cursor = 0;
|
|
39
|
+
const whatIsNew = async () => {
|
|
40
|
+
for (const entry of await entriesOf(door, call, { after: cursor })) {
|
|
41
|
+
cursor = entry.seq;
|
|
42
|
+
absorb(entry);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
while (running) {
|
|
46
|
+
await whatIsNew();
|
|
47
|
+
await new Promise((wake) => setTimeout(wake, every));
|
|
48
|
+
}
|
|
49
|
+
// One last pass: the closing turns land between two polls, and a transcript that stops a line
|
|
50
|
+
// short of the hangup is worse than no transcript at all.
|
|
51
|
+
await whatIsNew();
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=voice.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/cli/testing/voice.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAE/F,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAUhD,gGAAgG;AAChG,0FAA0F;AAC1F,kEAAkE;AAClE,MAAM,CAAC,MAAM,QAAQ,GAAa,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AASxE,oGAAoG;AACpG,MAAM,UAAU,OAAO;IACrB,OAAO,QAAQ,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;AACnD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAU,EACV,MAA6F;IAE7F,OAAO,MAAM,KAAK,CAAS,IAAI,EAAE,iBAAiB,EAAE;QAClD,MAAM,EAAE,MAAM;QACd,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;SAC3B;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAU,EACV,IAAY,EACZ,IAAsB,EACtB,MAA8B,EAC9B,KAAK,GAAG,GAAG;IAEX,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,iGAAiG;IACjG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;IAClE,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE;QAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;YACnE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC;YACnB,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IACF,OAAO,OAAO,EAAE,CAAC;QACf,MAAM,SAAS,EAAE,CAAC;QAClB,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,8FAA8F;IAC9F,0DAA0D;IAC1D,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--ground:#0d0d0f;--panel:#101013;--panel-2:#16161a;--panel-3:#202028;--edge:#24242a;--edge-strong:#24242a;--edge-soft:#1c1c22;--ink:#ececec;--ink-2:#c9c9d0;--ink-soft:#8b8b93;--ink-faint:#5c5c66;--accent:#f0569a;--accent-soft:#1a1217;--accent-line:#3a2130;--on-accent:#fff;--ok:#7fae86;--warn:#cfae7e;--face:"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;--face-fixed:"IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;--sunk:#0a0a0c;--hover:#1a1a20;--selected:#202028;--step:8px;--rail:204px;--head:50px;--radius:4px;--radius-control:5px;--radius-panel:8px}:root[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--ground:#f6f6f4;--panel:#fff;--panel-2:#fbfbf9;--panel-3:#eaeae6;--edge:#e3e3de;--edge-strong:#e3e3de;--edge-soft:#ededea;--ink:#17171a;--ink-2:#3e3e45;--ink-soft:#74747c;--ink-faint:#a4a4ac;--accent:#c92572;--accent-soft:#fdf1f6;--accent-line:#f0cfdf;--ok:#3d7a4c;--warn:#8a6a2c;--sunk:#f1f1ee;--hover:#f1f1ee;--selected:#eaeae6}.page{min-width:0;max-width:1040px;padding:26px 28px 34px}.page-wide{max-width:1320px}.page-eyebrow{color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.06em;text-transform:uppercase;font-size:10.5px}.page-title{letter-spacing:-.01em;margin:4px 0 0;font-size:20px;font-weight:500}.page-title-fixed{font-family:var(--face-fixed);letter-spacing:0}.page-lede{color:var(--ink-soft);text-wrap:pretty;max-width:68ch;margin:6px 0 0;font-size:14px}.section{margin-top:22px}.section-title{color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.06em;text-transform:uppercase;margin:0 0 10px;font-size:10.5px;font-weight:400}.note{color:var(--ink-faint);font-family:var(--face-fixed);text-wrap:pretty;margin:14px 0 0;font-size:11px}.note+.panel{margin-top:14px}.note-warn{color:var(--accent)}.panel{background:var(--panel);border:1px solid var(--edge);border-radius:var(--radius-panel);overflow:hidden}.panel-head{border-bottom:1px solid var(--edge);justify-content:space-between;align-items:baseline;gap:12px;padding:10px 14px;display:flex}.panel-title{color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.06em;text-transform:uppercase;margin:0;font-size:10.5px;font-weight:400}.panel-body{padding:12px 14px;font-size:13px}.grid{gap:14px;display:grid}.grid-3{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}.badge{color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.06em;text-transform:uppercase;white-space:nowrap;font-size:10.5px}.badge-live{background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:var(--radius);color:var(--accent);padding:1px 6px}.mono{font-family:var(--face-fixed);font-size:.92em}.dim{color:var(--ink-soft)}.faint{color:var(--ink-faint)}.accent{color:var(--accent)}.table-wrap{background:var(--panel);border:1px solid var(--edge);border-radius:var(--radius-panel);overflow-x:auto}.table{border-collapse:collapse;width:100%;font-size:13px}.table th{border-bottom:1px solid var(--edge);color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.06em;text-align:left;text-transform:uppercase;white-space:nowrap;padding:9px 16px;font-size:10.5px;font-weight:400}.table td{border-bottom:1px solid var(--edge-soft);vertical-align:baseline;padding:11px 16px}.table tbody tr:last-child td{border-bottom:none}.table tbody tr:hover td{background:var(--hover)}.table td.num,.table th.num{font-family:var(--face-fixed);font-variant-numeric:tabular-nums;text-align:right;font-size:11.5px}.table td.id{font-family:var(--face-fixed);font-size:12px}.table td.id .link{color:var(--accent);font-size:12px}tr.is-open td{background:var(--selected)}.kv{border-collapse:collapse;width:100%}.kv td{font-family:var(--face-fixed);padding:4px 0;font-size:11.5px}.kv-key{color:var(--ink-soft)}.kv-val{color:var(--ink-2);font-variant-numeric:tabular-nums;text-align:right}.chips{flex-wrap:wrap;gap:5px 7px;display:flex}.chip{border:1px solid var(--edge);border-radius:var(--radius);color:var(--ink-2);font-family:var(--face-fixed);align-items:baseline;gap:4px;padding:1px 5px;font-size:10.5px;display:inline-flex}.chip-key{color:var(--ink-soft)}.chip-val{color:var(--ink-2);font-variant-numeric:tabular-nums}.tabs{background:var(--sunk);border:1px solid var(--edge);border-radius:var(--radius-control);height:28px;margin-top:22px;display:inline-flex;overflow:hidden}.tab{border:none;border-right:1px solid var(--edge);color:var(--ink-soft);cursor:pointer;font-family:var(--face-fixed);background:0 0;height:100%;padding:0 10px;font-size:11.5px}.tab:last-child{border-right:none}.tab:hover{color:var(--ink)}.tab:focus-visible{outline-offset:-2px}.tab.is-active{background:var(--selected);color:var(--ink)}.button{border:1px solid var(--edge);border-radius:var(--radius-control);color:var(--ink-2);cursor:pointer;white-space:nowrap;background:0 0;align-items:center;gap:7px;height:28px;padding:0 10px;font-size:12.5px;display:inline-flex}.button:hover:not(:disabled){border-color:var(--ink);color:var(--ink)}.button:disabled{cursor:default;opacity:.4}.button-accent{background:var(--accent);border-color:var(--accent);color:var(--on-accent);height:30px;padding:0 14px;font-weight:500}.button-accent:hover:not(:disabled){border-color:var(--accent);color:var(--on-accent)}.input{background:var(--sunk);border:1px solid var(--edge);border-radius:var(--radius-control);color:var(--ink-2);min-width:0;padding:5px 8px;font-size:12.5px}.input:focus{color:var(--ink)}.input::placeholder{color:var(--ink-faint)}.link{color:var(--ink-soft);cursor:pointer;font-family:var(--face-fixed);background:0 0;border:none;padding:0;font-size:11.5px}.link:hover{color:var(--accent)}.empty{max-width:72ch;padding-top:8px}.empty-title{margin:0;font-size:15px;font-weight:500}.empty-body{color:var(--ink-soft);text-wrap:pretty;margin:8px 0 0;font-size:13.5px;line-height:1.6}.way{background:var(--ground);justify-content:center;align-items:center;min-height:100%;padding:32px 20px;display:flex}.way-card{background:var(--panel);border:1px solid var(--edge);border-radius:var(--radius-panel);flex-direction:column;width:100%;max-width:25rem;padding:28px 28px 24px;display:flex}.way-mark{color:var(--ink-faint);font-family:var(--face-fixed);letter-spacing:.02em;align-items:baseline;gap:6px;margin-bottom:20px;font-size:11.5px;display:flex}.way-mark b{color:var(--ink);font-weight:500}.way-title{color:var(--ink);letter-spacing:-.015em;margin:0 0 6px;font-size:20px;font-weight:500}.way-lede{color:var(--ink-soft);text-wrap:pretty;margin:0 0 22px;font-size:13.5px;line-height:1.55}.way-fields{flex-direction:column;gap:14px;display:flex}.way-field{flex-direction:column;gap:6px;display:flex}.way-label{color:var(--ink-2);font-size:12px;font-weight:500}.way-label span{color:var(--ink-faint);font-family:var(--face-fixed);margin-left:6px;font-size:11px;font-weight:400}.way-input{background:var(--sunk);border:1px solid var(--ink-faint);border-radius:var(--radius-control);color:var(--ink);font-family:var(--face);width:100%;height:38px;padding:0 11px;font-size:14px}.way-input:focus{border-color:var(--accent);outline:none}.way-input::placeholder{color:var(--ink-faint)}.way-go{background:var(--ink);border:1px solid var(--ink);border-radius:var(--radius-control);color:var(--ground);cursor:pointer;font-family:var(--face);justify-content:center;align-items:center;width:100%;height:38px;margin-top:22px;font-size:14px;font-weight:500;display:inline-flex}.way-go:hover:not(:disabled){opacity:.9}.way-go:disabled{cursor:not-allowed;opacity:.4}.way-refused{border-left:2px solid var(--accent);color:var(--ink-2);text-wrap:pretty;margin:18px 0 0;padding-left:10px;font-size:13px;line-height:1.5}.way-else{border-top:1px solid var(--edge-soft);color:var(--ink-soft);text-wrap:pretty;flex-direction:column;gap:8px;margin-top:24px;padding-top:18px;font-size:12.5px;line-height:1.5;display:flex}.way-else p{margin:0}.way-else code{color:var(--ink-2);font-family:var(--face-fixed);font-size:12px}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{background:var(--ground);color:var(--ink);font-family:var(--face);-webkit-font-smoothing:antialiased;font-size:15px;font-weight:400;line-height:1.55}a{color:inherit;text-decoration:none}button,input,select,textarea{font:inherit}:focus-visible{outline:1px solid var(--accent);outline-offset:2px}::selection{background:var(--accent-line)}.fixed{font-family:var(--face-fixed);font-size:12px}@keyframes pulse{0%,to{opacity:.35}50%{opacity:1}}@keyframes blink{0%,49%{opacity:1}50%,to{opacity:0}}::-webkit-scrollbar{width:10px;height:10px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--panel-3);border:3px solid var(--ground);border-radius:6px}::-webkit-scrollbar-thumb:hover{background:var(--ink-faint)}.shell{flex-direction:column;height:100%;display:flex}.shell-head{background:var(--panel);border-bottom:1px solid var(--edge);min-height:var(--head);flex-wrap:wrap;flex:none;align-items:center;gap:18px;padding:0 16px;display:flex}.shell-body{grid-template-columns:minmax(0, var(--rail)) minmax(0, 1fr);flex:1;min-height:0;display:grid}.shell-rail{background:var(--panel-2);border-right:1px solid var(--edge);flex-direction:column;min-width:0;display:flex;overflow-y:auto}.shell-screen{flex-direction:column;min-width:0;display:flex;overflow:auto}.brand{flex:none;align-items:center;gap:9px;display:flex}.brand-mark{height:18px;display:block}.brand-name{letter-spacing:-.01em;font-size:12.5px}.brand-sep{color:var(--ink-faint)}.brand-kind{color:var(--ink-soft)}.head-crumbs{color:var(--ink-soft);align-items:center;gap:7px;min-width:0;display:flex}.head-crumbs b{color:var(--ink);font-weight:500}.head-sep{color:var(--ink-faint)}.head-right{flex-wrap:wrap;align-items:center;gap:14px;margin-left:auto;display:flex}.head-whose{color:var(--ink-soft);font-size:11.5px}.theme-toggle,.head-leave{border:1px solid var(--edge);color:var(--ink-soft);cursor:pointer;background:0 0;border-radius:6px;align-items:center;gap:7px;height:26px;padding:0 9px;font-size:11px;display:inline-flex}.theme-toggle:hover,.head-leave:hover{border-color:var(--ink);color:var(--ink)}.theme-dot{background:var(--ink);border-radius:50%;width:8px;height:8px;display:block}.rail-group{padding:14px 12px 6px}.rail-label{color:var(--ink-faint);letter-spacing:.06em;text-transform:uppercase;margin:0 0 8px;padding:0 9px;font-size:10.5px}.rail-links{flex-direction:column;gap:1px;display:flex}.rail-link{color:var(--ink-soft);border-left:2px solid #0000;border-radius:0 5px 5px 0;justify-content:space-between;align-items:center;gap:8px;padding:6px 9px;font-size:13.5px;display:flex}.rail-link:hover{background:var(--hover)}.rail-link-here{background:var(--selected);border-left-color:var(--accent);color:var(--ink)}.rail-hint{color:var(--ink-faint);font-size:10px}.rail-foot{border-top:1px solid var(--edge);color:var(--ink-soft);margin-top:auto;padding:14px 21px 16px;font-size:10.5px;line-height:1.8}.rail-foot-line{color:var(--ink-faint)}.nothing{color:var(--ink-faint);font-family:var(--face-fixed);text-wrap:pretty;max-width:64ch;margin:0;font-size:11.5px}.nothing .fixed{color:var(--ink-2);font-size:inherit}.workers{margin:22px 0 0;padding:0;list-style:none}.worker{border-bottom:1px solid var(--edge-soft);grid-template-columns:minmax(0,1fr) 110px 120px 110px auto;align-items:baseline;gap:14px;padding:10px 16px;display:grid}.worker:last-child{border-bottom:none}.worker-quiet{opacity:.55}.worker-load{color:var(--ink-soft);font-size:11.5px}.worker-standing{color:var(--ink-faint);font-size:10.5px}@media (width<=860px){.worker{grid-template-columns:minmax(0,1fr) auto}}.tenants{margin:22px 0 0;padding:0;list-style:none}.tenant{border-bottom:1px solid var(--edge-soft);grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;align-items:baseline;gap:16px;padding:11px 16px;display:grid}.tenant:last-child{border-bottom:none}.tenant:hover{background:var(--hover)}.tenant-id{color:var(--ink-soft);font-size:12px}.tenant-make{margin-top:22px}.tenant-make-form{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;align-items:center;gap:10px;padding:14px;display:grid}.limits{grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px 16px;padding:14px 16px;display:grid}.limit{flex-direction:column;gap:4px;display:flex}.limit-name{color:var(--ink-soft);font-size:11px}.limit-held{color:var(--ink-faint);font-size:10.5px}.limit-input{width:100%}.limits-save{align-items:center;gap:12px;padding:0 16px 14px;display:flex}.of-the-org-panel{margin-top:22px}.of-the-org-empty{padding:0 16px 14px}.of-the-org-note{padding:0 16px 12px}.of-the-org{margin:0;padding:0;list-style:none}.of-the-org li{border-bottom:1px solid var(--edge-soft);grid-template-columns:minmax(0,1fr) 110px minmax(0,1fr) auto;align-items:baseline;gap:14px;padding:9px 16px;display:grid}.of-the-org li:last-child{border-bottom:none}.gone{opacity:.55}@media (width<=760px){.tenant,.tenant-make-form,.of-the-org li{grid-template-columns:minmax(0,1fr)}}.doors-pick{flex-wrap:wrap;align-items:center;gap:10px;margin-top:22px;display:flex}.doors{margin:22px 0 0;padding:0;list-style:none}.door{border-bottom:1px solid var(--edge-soft);grid-template-columns:minmax(0,1.2fr) 90px minmax(0,1fr) 110px;align-items:baseline;gap:14px;padding:10px 16px;display:grid}.door:last-child{border-bottom:none}.door-source{color:var(--ink-faint);font-size:10.5px}@media (width<=760px){.door{grid-template-columns:minmax(0,1fr)}}.consumed{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;margin-top:22px;display:grid}.consumed-org{padding:14px 16px}.consumed-name{margin:0 0 8px;font-size:13px}.consumed-figure{color:var(--ink-soft);font-size:11.5px}.metered{border-collapse:collapse;width:100%;font-size:12px}.metered th{border-bottom:1px solid var(--edge);color:var(--ink-faint);letter-spacing:.05em;text-align:left;text-transform:uppercase;padding:8px 10px;font-size:10.5px;font-weight:500}.metered td{border-bottom:1px solid var(--edge-soft);white-space:nowrap;padding:7px 10px}.metered tr:last-child td{border-bottom:none}.metered-scroll{margin-top:22px;overflow-x:auto}.metered-more{align-items:center;gap:12px;padding:12px 16px;display:flex}
|