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,174 @@
|
|
|
1
|
+
/** `pinecall knowledge push | list | drop | eval`: the base the agent answers from, and what a golden says of it. */
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { parseArgs } from "node:util";
|
|
5
|
+
import { slugOf } from "../runtime/connect.js";
|
|
6
|
+
import { theDoor } from "./env.js";
|
|
7
|
+
import { load } from "./load.js";
|
|
8
|
+
import { asked } from "./testing/gateway.js";
|
|
9
|
+
import { refusal } from "./whoami.js";
|
|
10
|
+
const USAGE = `usage: pinecall knowledge push [dir] [--base <name>] [--file agent.tsx]
|
|
11
|
+
pinecall knowledge list
|
|
12
|
+
pinecall knowledge drop <base>
|
|
13
|
+
pinecall knowledge eval [golden.json] [--base <name>] [--k <n>] [--file agent.tsx]`;
|
|
14
|
+
/** Where a base is refused before a byte is sent: the three sentences both doors say. */
|
|
15
|
+
export const NO_DIRECTORY = (directory) => `no knowledge directory at ${directory}`;
|
|
16
|
+
export const NO_MARKDOWN = (directory) => `no *.md under ${directory}: nothing to push`;
|
|
17
|
+
export const NO_GOLDEN = (golden) => `no golden at ${golden}: a JSON list of {asks, expects}`;
|
|
18
|
+
export const AN_EMPTY_GOLDEN = (golden) => `${golden} holds no questions: a golden is a JSON list of {asks, expects}`;
|
|
19
|
+
// The golden beside the documents it asks about: the questions the base is held to, and the chunk
|
|
20
|
+
// each should have found. `knowledge/golden.json` is where `eval` looks when nobody says.
|
|
21
|
+
export const DEFAULT_GOLDEN = "knowledge/golden.json";
|
|
22
|
+
// Where a tenant keeps what is retrieved per turn, beside the agent file: the layout every
|
|
23
|
+
// example has, and the one `docs = "<base>"` on the class was pushed from.
|
|
24
|
+
export const DEFAULT_DIR = "knowledge/docs";
|
|
25
|
+
export const group = {
|
|
26
|
+
purpose: "push | list | drop the knowledge base the agent answers from",
|
|
27
|
+
usage: `${USAGE}
|
|
28
|
+
|
|
29
|
+
push reads every *.md under the directory (./knowledge/docs beside the agent file when none
|
|
30
|
+
is named) and sends the folder whole to PUT /v1/knowledge/<base>: the base is replaced, never
|
|
31
|
+
merged. The base is the agent's slug unless --base says otherwise, and the class names it with
|
|
32
|
+
\`docs = "<base>"\`. list prints every base this org has pushed; drop removes one.
|
|
33
|
+
|
|
34
|
+
eval asks the base every question of a golden — a JSON list of {asks, expects}, where expects is
|
|
35
|
+
the heading path the answer should carry — and prints recall@k and nDCG@10, computed by code with
|
|
36
|
+
no model in the loop, plus every question it missed and what came back instead. A golden is fixed
|
|
37
|
+
and the index is the variable: never soften a question so a change can pass.`,
|
|
38
|
+
run,
|
|
39
|
+
};
|
|
40
|
+
/** Read the sub-verb and do it: the folder to the gateway, the list off it, or one base gone. */
|
|
41
|
+
export async function run(argv, how = {}) {
|
|
42
|
+
const out = how.out ?? process.stdout;
|
|
43
|
+
const err = how.err ?? process.stderr;
|
|
44
|
+
const { values, positionals } = parseArgs({
|
|
45
|
+
args: argv,
|
|
46
|
+
allowPositionals: true,
|
|
47
|
+
options: { base: { type: "string" }, file: { type: "string" }, k: { type: "string" } },
|
|
48
|
+
});
|
|
49
|
+
const [verb, ...rest] = positionals;
|
|
50
|
+
const door = theDoor(how.env ?? process.env, err);
|
|
51
|
+
if (door === undefined)
|
|
52
|
+
return 2;
|
|
53
|
+
try {
|
|
54
|
+
if (verb === "push")
|
|
55
|
+
return await push(door, rest[0], values.base, values.file, out, err);
|
|
56
|
+
if (verb === "list")
|
|
57
|
+
return await list(door, out);
|
|
58
|
+
if (verb === "drop" && rest[0] !== undefined)
|
|
59
|
+
return await drop(door, rest[0], out);
|
|
60
|
+
if (verb === "eval")
|
|
61
|
+
return await evaluate(door, rest[0], values.base, values.k, values.file, out, err);
|
|
62
|
+
}
|
|
63
|
+
catch (refused) {
|
|
64
|
+
// The gateway's own sentence, as it was said: "this gateway keeps no knowledge: it runs on
|
|
65
|
+
// a dev key" names the fix, and nothing here knows better.
|
|
66
|
+
err.write(`${refusal(refused)}\n`);
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
err.write(`${USAGE}\n`);
|
|
70
|
+
return 2;
|
|
71
|
+
}
|
|
72
|
+
// The folder as of now, whole. The directory and the base default to what the agent file says —
|
|
73
|
+
// `./knowledge/docs` beside it and its slug — and the class is loaded only when one of the two is
|
|
74
|
+
// missing, so a push that names both costs no TypeScript loader.
|
|
75
|
+
async function push(door, dir, base, agent, out, err) {
|
|
76
|
+
const loaded = dir === undefined || base === undefined ? await load(agent) : undefined;
|
|
77
|
+
const directory = resolve(dir ?? join(dirname(loaded.file), DEFAULT_DIR));
|
|
78
|
+
const name = base ?? slugOf(loaded.ctor);
|
|
79
|
+
if (!existsSync(directory) || !statSync(directory).isDirectory()) {
|
|
80
|
+
err.write(`${NO_DIRECTORY(directory)}\n`);
|
|
81
|
+
return 2;
|
|
82
|
+
}
|
|
83
|
+
const files = markdownUnder(directory);
|
|
84
|
+
if (files.length === 0) {
|
|
85
|
+
err.write(`${NO_MARKDOWN(directory)}\n`);
|
|
86
|
+
return 2;
|
|
87
|
+
}
|
|
88
|
+
out.write(`${pushedLine(await pushedTo(door, name, files), files.length)}\n`);
|
|
89
|
+
return 0;
|
|
90
|
+
}
|
|
91
|
+
async function list(door, out) {
|
|
92
|
+
const answered = await asked(door, "/v1/knowledge");
|
|
93
|
+
if (answered.bases.length === 0) {
|
|
94
|
+
out.write(`no knowledge base pushed yet: pinecall knowledge push ./knowledge/docs --base <slug>\n`);
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
for (const base of answered.bases) {
|
|
98
|
+
out.write(`${base.base} · ${base.chunks} chunks · pushed ${dayAndTime(base.pushed_at)}\n`);
|
|
99
|
+
}
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
async function drop(door, base, out) {
|
|
103
|
+
await asked(door, `/v1/knowledge/${encodeURIComponent(base)}`, { method: "DELETE" });
|
|
104
|
+
out.write(`dropped ${base}\n`);
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
// A golden is run when somebody changed the documents, the embedder or a knob — never on a
|
|
108
|
+
// caller's clock — so it reads its questions off the disk and asks them one at a time.
|
|
109
|
+
async function evaluate(door, file, base, k, agent, out, err) {
|
|
110
|
+
const loaded = file === undefined || base === undefined ? await load(agent) : undefined;
|
|
111
|
+
const golden = resolve(file ?? join(dirname(loaded.file), DEFAULT_GOLDEN));
|
|
112
|
+
const name = base ?? slugOf(loaded.ctor);
|
|
113
|
+
if (!existsSync(golden)) {
|
|
114
|
+
err.write(`${NO_GOLDEN(golden)}\n`);
|
|
115
|
+
return 2;
|
|
116
|
+
}
|
|
117
|
+
const questions = theQuestionsIn(golden);
|
|
118
|
+
if (questions === null) {
|
|
119
|
+
err.write(`${AN_EMPTY_GOLDEN(golden)}\n`);
|
|
120
|
+
return 2;
|
|
121
|
+
}
|
|
122
|
+
const score = await scoredOn(door, name, questions, k === undefined ? undefined : Number(k));
|
|
123
|
+
out.write(`${scoreLines(score).join("\n")}\n`);
|
|
124
|
+
return score.misses.length === 0 ? 0 : 1;
|
|
125
|
+
}
|
|
126
|
+
/** The folder, sent whole: the base is replaced and never merged. Both doors push through here. */
|
|
127
|
+
export async function pushedTo(door, base, files) {
|
|
128
|
+
return await asked(door, `/v1/knowledge/${encodeURIComponent(base)}`, {
|
|
129
|
+
method: "PUT",
|
|
130
|
+
body: { files },
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/** Every question of a golden asked of the base, and the two figures code computed from it. */
|
|
134
|
+
export async function scoredOn(door, base, questions, k) {
|
|
135
|
+
return await asked(door, `/v1/knowledge/${encodeURIComponent(base)}/eval`, {
|
|
136
|
+
method: "POST",
|
|
137
|
+
body: { questions, ...(k === undefined ? {} : { k }) },
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/** The questions a golden file holds, or nothing at all when it holds none. */
|
|
141
|
+
export function theQuestionsIn(golden) {
|
|
142
|
+
const questions = JSON.parse(readFileSync(golden, "utf8"));
|
|
143
|
+
return Array.isArray(questions) && questions.length > 0 ? questions : null;
|
|
144
|
+
}
|
|
145
|
+
/** What a golden prints: the two figures on one line, then a line per question the base missed. */
|
|
146
|
+
export function scoreLines(score) {
|
|
147
|
+
const figures = `${score.base} · ${score.model} · ${score.questions} questions · ` +
|
|
148
|
+
`recall@${score.k} ${score.recall_at_k.toFixed(2)} · nDCG@10 ${score.ndcg_at_10.toFixed(2)} · ` +
|
|
149
|
+
`${Math.round(score.took_ms)} ms`;
|
|
150
|
+
return [
|
|
151
|
+
figures,
|
|
152
|
+
...score.misses.map((missed) => ` missed: ${missed.asks} → wanted ${missed.expects}, got ${missed.found[0] ?? "nothing"}`),
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
/** The one line a push prints: the base, what was sent, what it became, and how long it took. */
|
|
156
|
+
export function pushedLine(pushed, files) {
|
|
157
|
+
return `${pushed.base} · ${files} files · ${pushed.chunks} chunks · ${Math.round(pushed.took_ms)} ms`;
|
|
158
|
+
}
|
|
159
|
+
/** Every *.md under a directory, its subdirectories included, as the wire carries a file: its path relative to the directory, and its text. */
|
|
160
|
+
export function markdownUnder(directory) {
|
|
161
|
+
const found = [];
|
|
162
|
+
for (const entry of readdirSync(directory, { recursive: true, withFileTypes: true })) {
|
|
163
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
164
|
+
continue;
|
|
165
|
+
const path = join(entry.parentPath, entry.name);
|
|
166
|
+
found.push({ path: relative(directory, path).split(sep).join("/"), text: readFileSync(path, "utf8") });
|
|
167
|
+
}
|
|
168
|
+
return found.sort((one, other) => (one.path < other.path ? -1 : 1));
|
|
169
|
+
}
|
|
170
|
+
/** Unix seconds as a person reads them: the day and the minute, in UTC, no fractions. */
|
|
171
|
+
export function dayAndTime(seconds) {
|
|
172
|
+
return new Date(seconds * 1000).toISOString().slice(0, 16).replace("T", " ");
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/cli/knowledge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** `pinecall line`: whose terminal a call at this agent's number rings in, and the claim that takes it. */
|
|
2
|
+
import type { TheLine } from "@pinecall/protocol";
|
|
3
|
+
import type { Group } from "./groups.js";
|
|
4
|
+
import { type Door } from "./testing/gateway.js";
|
|
5
|
+
export declare const group: Group;
|
|
6
|
+
export declare function run(argv: string[], out?: NodeJS.WritableStream): Promise<number>;
|
|
7
|
+
/** Say which phone is yours: every call it makes reaches your own agent, in whatever you hold. */
|
|
8
|
+
export declare function callsFrom(door: Door, number: string): Promise<{
|
|
9
|
+
calling: string[];
|
|
10
|
+
}>;
|
|
11
|
+
/** Stop answering your own calls: they fall back to whoever holds the line. */
|
|
12
|
+
export declare function forgetCallsFrom(door: Door): Promise<{
|
|
13
|
+
forgot: string[];
|
|
14
|
+
}>;
|
|
15
|
+
/** What the terminal says back once a number is yours. */
|
|
16
|
+
export declare function calling(numbers: string[]): string;
|
|
17
|
+
/** And when they stop. A `forget` that forgot nothing says so rather than looking like it worked. */
|
|
18
|
+
export declare function forgotten(numbers: string[]): string;
|
|
19
|
+
/** Who is answering this agent's ringing doors right now. */
|
|
20
|
+
export declare function theLine(door: Door, slug: string): Promise<TheLine>;
|
|
21
|
+
/** Take it for this terminal, whoever had it. */
|
|
22
|
+
export declare function claimed(door: Door, slug: string): Promise<TheLine>;
|
|
23
|
+
/** Give it up: whoever else is still running the agent picks it up. */
|
|
24
|
+
export declare function released(door: Door, slug: string): Promise<TheLine>;
|
|
25
|
+
/**
|
|
26
|
+
* The line as a person reads it: where the ring lands, and the move that changes it.
|
|
27
|
+
*
|
|
28
|
+
* It never prints a member id. A person recognises a colleague by their email and nothing else,
|
|
29
|
+
* and a corner nobody is named in — the org's own key, CI's — is said as what it is rather than
|
|
30
|
+
* as a null.
|
|
31
|
+
*/
|
|
32
|
+
export declare function describing(said: TheLine): string;
|
|
33
|
+
//# sourceMappingURL=line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line.d.ts","sourceRoot":"","sources":["../../src/cli/line.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAE3G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIlD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAQxD,eAAO,MAAM,KAAK,EAAE,KAkBnB,CAAC;AAIF,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,GAAE,MAAM,CAAC,cAA+B,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCtG;AAED,kGAAkG;AAClG,wBAAsB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE1F;AAED,+EAA+E;AAC/E,wBAAsB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAE/E;AAED,0DAA0D;AAC1D,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAIjD;AAED,qGAAqG;AACrG,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAInD;AAED,6DAA6D;AAC7D,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE;AAED,iDAAiD;AACjD,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAExE;AAED,uEAAuE;AACvE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzE;AAUD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAWhD"}
|
package/dist/cli/line.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/** `pinecall line`: whose terminal a call at this agent's number rings in, and the claim that takes it. */
|
|
2
|
+
import { callsFrom as keptOnTheProfile } from "./profiles.js";
|
|
3
|
+
import { theDoor } from "./env.js";
|
|
4
|
+
import { load } from "./load.js";
|
|
5
|
+
import { slugOf } from "../runtime/connect.js";
|
|
6
|
+
import { asked } from "./testing/gateway.js";
|
|
7
|
+
const USAGE = "usage: pinecall line [from <+number> | forget | claim | release] [agent.tsx]";
|
|
8
|
+
// A number exists once in a world, so it rings in one place. In production that place is the box
|
|
9
|
+
// and there is nothing to decide; in the sandbox an org shares ONE number and three developers
|
|
10
|
+
// may be running the same agent, so which terminal it rings in is claimed out loud. Alone nobody
|
|
11
|
+
// claims anything — the first `pinecall run` takes it. See the runtime's docs/protocol/gateway-api.md.
|
|
12
|
+
export const group = {
|
|
13
|
+
purpose: "whose terminal the sandbox number rings in",
|
|
14
|
+
usage: `${USAGE}
|
|
15
|
+
|
|
16
|
+
With nothing after it: who is answering this agent's number right now, and who else is running
|
|
17
|
+
it and could take it.
|
|
18
|
+
|
|
19
|
+
\`from <+number>\` is the one you want. Say which phone is YOURS, once, and every call you make
|
|
20
|
+
to a sandbox number reaches your own agent — no claim, no coordination, and three of you
|
|
21
|
+
testing at the same time. It is remembered for this gateway and re-sent by every
|
|
22
|
+
\`pinecall run\`. \`forget\` undoes it.
|
|
23
|
+
|
|
24
|
+
\`claim\` and \`release\` are the fallback, for a call from a number nobody said was theirs — a
|
|
25
|
+
customer, a colleague's phone. The first terminal to hold the agent has it; alone, you never
|
|
26
|
+
need either word.
|
|
27
|
+
|
|
28
|
+
The agent is the one in this directory, so nothing has to be named.`,
|
|
29
|
+
run,
|
|
30
|
+
};
|
|
31
|
+
const VERBS = new Set(["from", "forget", "claim", "release"]);
|
|
32
|
+
export async function run(argv, out = process.stdout) {
|
|
33
|
+
const [verb, ...rest] = VERBS.has(argv[0] ?? "") ? argv : ["show", ...argv];
|
|
34
|
+
const door = theDoor();
|
|
35
|
+
if (door === undefined)
|
|
36
|
+
return 2;
|
|
37
|
+
// `from` and `forget` are about the PERSON and not about one agent, so neither loads a class:
|
|
38
|
+
// a phone is yours in whatever directory you are standing in.
|
|
39
|
+
if (verb === "from") {
|
|
40
|
+
const number = rest[0];
|
|
41
|
+
if (number === undefined) {
|
|
42
|
+
process.stderr.write(`${USAGE}\n`);
|
|
43
|
+
return 2;
|
|
44
|
+
}
|
|
45
|
+
const said = await callsFrom(door, number);
|
|
46
|
+
keptOnTheProfile(number);
|
|
47
|
+
out.write(`${calling(said.calling)}\n`);
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
if (verb === "forget") {
|
|
51
|
+
const said = await forgetCallsFrom(door);
|
|
52
|
+
keptOnTheProfile(undefined);
|
|
53
|
+
out.write(`${forgotten(said.forgot)}\n`);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
const slug = slugOf((await load(rest[0])).ctor);
|
|
57
|
+
const said = verb === "claim"
|
|
58
|
+
? await claimed(door, slug)
|
|
59
|
+
: verb === "release"
|
|
60
|
+
? await released(door, slug)
|
|
61
|
+
: await theLine(door, slug);
|
|
62
|
+
out.write(`${describing(said)}\n`);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
/** Say which phone is yours: every call it makes reaches your own agent, in whatever you hold. */
|
|
66
|
+
export async function callsFrom(door, number) {
|
|
67
|
+
return await asked(door, FROM, { method: "PUT", body: { number } });
|
|
68
|
+
}
|
|
69
|
+
/** Stop answering your own calls: they fall back to whoever holds the line. */
|
|
70
|
+
export async function forgetCallsFrom(door) {
|
|
71
|
+
return await asked(door, FROM, { method: "DELETE" });
|
|
72
|
+
}
|
|
73
|
+
/** What the terminal says back once a number is yours. */
|
|
74
|
+
export function calling(numbers) {
|
|
75
|
+
return numbers.length === 1
|
|
76
|
+
? `calls from ${numbers[0]} reach this terminal`
|
|
77
|
+
: `calls from ${numbers.join(", ")} reach this terminal`;
|
|
78
|
+
}
|
|
79
|
+
/** And when they stop. A `forget` that forgot nothing says so rather than looking like it worked. */
|
|
80
|
+
export function forgotten(numbers) {
|
|
81
|
+
return numbers.length === 0
|
|
82
|
+
? "no number was reaching this terminal"
|
|
83
|
+
: `calls from ${numbers.join(", ")} no longer reach this terminal`;
|
|
84
|
+
}
|
|
85
|
+
/** Who is answering this agent's ringing doors right now. */
|
|
86
|
+
export async function theLine(door, slug) {
|
|
87
|
+
return await asked(door, path(slug));
|
|
88
|
+
}
|
|
89
|
+
/** Take it for this terminal, whoever had it. */
|
|
90
|
+
export async function claimed(door, slug) {
|
|
91
|
+
return await asked(door, path(slug), { method: "POST" });
|
|
92
|
+
}
|
|
93
|
+
/** Give it up: whoever else is still running the agent picks it up. */
|
|
94
|
+
export async function released(door, slug) {
|
|
95
|
+
return await asked(door, path(slug), { method: "DELETE" });
|
|
96
|
+
}
|
|
97
|
+
function path(slug) {
|
|
98
|
+
return `/v1/agents/${encodeURIComponent(slug)}/line`;
|
|
99
|
+
}
|
|
100
|
+
// A phone is a PERSON's and not an agent's, so this door sits above the agents: say it once and
|
|
101
|
+
// it works on every agent you hold.
|
|
102
|
+
const FROM = "/v1/line/from";
|
|
103
|
+
/**
|
|
104
|
+
* The line as a person reads it: where the ring lands, and the move that changes it.
|
|
105
|
+
*
|
|
106
|
+
* It never prints a member id. A person recognises a colleague by their email and nothing else,
|
|
107
|
+
* and a corner nobody is named in — the org's own key, CI's — is said as what it is rather than
|
|
108
|
+
* as a null.
|
|
109
|
+
*/
|
|
110
|
+
export function describing(said) {
|
|
111
|
+
if (!said.held)
|
|
112
|
+
return `nobody is answering ${said.agent}: start \`pinecall run\``;
|
|
113
|
+
// Yours by number beats yours by line, and is said first: it is the one that needs no upkeep.
|
|
114
|
+
const mine = said.calling.length > 0 ? `your calls from ${said.calling.join(", ")}` : undefined;
|
|
115
|
+
if (said.yours) {
|
|
116
|
+
const also = [mine, whoElse(said)].filter((part) => part !== undefined);
|
|
117
|
+
return ["rings in this terminal", ...also].join(" · ");
|
|
118
|
+
}
|
|
119
|
+
const theirs = `rings in ${whose(said)}`;
|
|
120
|
+
if (mine !== undefined)
|
|
121
|
+
return `${theirs}, but not ${mine}`;
|
|
122
|
+
return `${theirs} · \`pinecall line from <+your-number>\` routes yours, or \`claim\` takes it`;
|
|
123
|
+
}
|
|
124
|
+
/** Whose terminal it rings in, for somebody reading a sentence about a colleague. */
|
|
125
|
+
function whose(said) {
|
|
126
|
+
const name = said.holding?.name;
|
|
127
|
+
return name === null || name === undefined ? "the terminal running the org's own key" : name;
|
|
128
|
+
}
|
|
129
|
+
/** Who else is running this agent and could take it, or nothing when nobody is. */
|
|
130
|
+
function whoElse(said) {
|
|
131
|
+
const names = said.waiting.map((one) => one.name ?? "the org's own key");
|
|
132
|
+
return names.length === 0 ? undefined : `also running: ${names.join(", ")}`;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line.js","sourceRoot":"","sources":["../../src/cli/line.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** `--listen`: one live call on this machine's speakers, from the terminal that opened it. */
|
|
2
|
+
import { type Door } from "./testing/gateway.js";
|
|
3
|
+
/** What a seat in a room is: LiveKit's two fields, and who this terminal is in that room. */
|
|
4
|
+
interface Seat {
|
|
5
|
+
server_url: string;
|
|
6
|
+
participant_token: string;
|
|
7
|
+
identity: string;
|
|
8
|
+
}
|
|
9
|
+
/** One ear in one call, and the way to take it out again. */
|
|
10
|
+
export interface Ear {
|
|
11
|
+
/** Who this terminal is in the room, for the line it prints. */
|
|
12
|
+
identity: string;
|
|
13
|
+
leave(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
/** What to say when this machine has no way to play raw audio, and what installs one. */
|
|
16
|
+
export declare const NO_PLAYER: string;
|
|
17
|
+
/** What to say when the room library is not installed: it is optional, and this is what wants it. */
|
|
18
|
+
export declare const NO_ROOM_LIBRARY: string;
|
|
19
|
+
/**
|
|
20
|
+
* A hidden, silent seat in one live call, with both tracks mixed onto this machine's speakers.
|
|
21
|
+
* It is the same seat the console's listen button takes — `POST /v1/calls/{call}/listen`, scope
|
|
22
|
+
* `observe` — and the caller is never told anybody joined. Nothing is recorded here: the runtime
|
|
23
|
+
* writes the recording, and this is only the ear.
|
|
24
|
+
*
|
|
25
|
+
* The room is joined in a process of its own (cli/ear.ts), because the room library is a native
|
|
26
|
+
* build with a logger this process cannot turn down and threads that would hold it open after the
|
|
27
|
+
* call. This side mints the seat, starts the player, and pipes the one into the other.
|
|
28
|
+
*/
|
|
29
|
+
export declare function anEarIn(door: Door, call: string, out: NodeJS.WritableStream): Promise<Ear>;
|
|
30
|
+
/**
|
|
31
|
+
* The seat, knocked for until the room opens. The gateway mints it off the call's snapshot and a
|
|
32
|
+
* simulation asks the moment it has an id — before the worker has joined — so asking once would
|
|
33
|
+
* be asking too early, and joining late is joining after the greeting.
|
|
34
|
+
*/
|
|
35
|
+
export declare function aSeatIn(door: Door, call: string): Promise<Seat>;
|
|
36
|
+
export declare const EAR: string;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=listening.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listening.d.ts","sourceRoot":"","sources":["../../src/cli/listening.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAQ9F,OAAO,EAAS,KAAK,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAExD,6FAA6F;AAC7F,UAAU,IAAI;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6DAA6D;AAC7D,MAAM,WAAW,GAAG;IAClB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA6BD,yFAAyF;AACzF,eAAO,MAAM,SAAS,QAE8D,CAAC;AAErF,qGAAqG;AACrG,eAAO,MAAM,eAAe,QAEqD,CAAC;AAElF;;;;;;;;;GASG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAoBhG;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUrE;AAID,eAAO,MAAM,GAAG,QAA2F,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/** `--listen`: one live call on this machine's speakers, from the terminal that opened it. */
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { delimiter, extname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { asked } from "./testing/gateway.js";
|
|
7
|
+
// The room's own rate and shape. Everything that reaches a room is 48 kHz mono — the caller's
|
|
8
|
+
// track is published at that rate (runtime evals/speech.py) — so the ear and the player agree on
|
|
9
|
+
// one number rather than each guessing.
|
|
10
|
+
const SAMPLE_RATE = 48_000;
|
|
11
|
+
const CHANNELS = 1;
|
|
12
|
+
// The seat is minted off the call's snapshot, which the gateway writes when the room opens. A
|
|
13
|
+
// simulation asks for its ear the moment it has an id, which is before the worker has joined, so
|
|
14
|
+
// the door is knocked at until it answers rather than once.
|
|
15
|
+
const A_ROOM_OPENS_WITHIN_MS = 30_000;
|
|
16
|
+
const A_KNOCK_EVERY_MS = 500;
|
|
17
|
+
// How long the ear is given to leave the room on its own before it is made to.
|
|
18
|
+
const LEAVING_TAKES_MS = 2_000;
|
|
19
|
+
// The ear's PCM comes out of its fd 3, never its stdout: the room library's own logger writes to
|
|
20
|
+
// stdout at debug and is exported nowhere, so stdout is the one place the samples could not go.
|
|
21
|
+
const PCM = 3;
|
|
22
|
+
/** The players this machine might have, in the order they are tried, each with its raw-audio flags. */
|
|
23
|
+
const PLAYERS = [
|
|
24
|
+
{ name: "ffplay", args: ["-hide_banner", "-loglevel", "error", "-nodisp", "-autoexit", "-f", "s16le", "-ar", String(SAMPLE_RATE), "-ac", String(CHANNELS), "-i", "-"] },
|
|
25
|
+
{ name: "play", args: ["-q", "-t", "raw", "-r", String(SAMPLE_RATE), "-e", "signed", "-b", "16", "-c", String(CHANNELS), "-"] },
|
|
26
|
+
{ name: "aplay", args: ["-q", "-f", "S16_LE", "-r", String(SAMPLE_RATE), "-c", String(CHANNELS), "-"] },
|
|
27
|
+
{ name: "pw-play", args: [`--format=s16`, `--rate=${SAMPLE_RATE}`, `--channels=${CHANNELS}`, "-"] },
|
|
28
|
+
];
|
|
29
|
+
/** What to say when this machine has no way to play raw audio, and what installs one. */
|
|
30
|
+
export const NO_PLAYER = `no player on this machine: --listen writes ${SAMPLE_RATE} Hz mono to one of ` +
|
|
31
|
+
`${PLAYERS.map((one) => one.name).join(", ")} — install ffmpeg, sox or alsa-utils`;
|
|
32
|
+
/** What to say when the room library is not installed: it is optional, and this is what wants it. */
|
|
33
|
+
export const NO_ROOM_LIBRARY = "--listen joins the call's room from this terminal and needs @livekit/rtc-node, which is an " +
|
|
34
|
+
"optional dependency: install it (pnpm add @livekit/rtc-node) and listen again";
|
|
35
|
+
/**
|
|
36
|
+
* A hidden, silent seat in one live call, with both tracks mixed onto this machine's speakers.
|
|
37
|
+
* It is the same seat the console's listen button takes — `POST /v1/calls/{call}/listen`, scope
|
|
38
|
+
* `observe` — and the caller is never told anybody joined. Nothing is recorded here: the runtime
|
|
39
|
+
* writes the recording, and this is only the ear.
|
|
40
|
+
*
|
|
41
|
+
* The room is joined in a process of its own (cli/ear.ts), because the room library is a native
|
|
42
|
+
* build with a logger this process cannot turn down and threads that would hold it open after the
|
|
43
|
+
* call. This side mints the seat, starts the player, and pipes the one into the other.
|
|
44
|
+
*/
|
|
45
|
+
export async function anEarIn(door, call, out) {
|
|
46
|
+
const player = aPlayer();
|
|
47
|
+
if (player === null)
|
|
48
|
+
throw new Error(NO_PLAYER);
|
|
49
|
+
theRoomLibrary();
|
|
50
|
+
const seat = await aSeatIn(door, call);
|
|
51
|
+
const ear = spawn(process.execPath, [...theLoaderFor(EAR), EAR, String(SAMPLE_RATE), String(CHANNELS)], {
|
|
52
|
+
stdio: ["pipe", "ignore", "ignore", "pipe"],
|
|
53
|
+
});
|
|
54
|
+
ear.stdio[PCM].pipe(player.stdin);
|
|
55
|
+
ear.stdin.write(`${JSON.stringify({ server_url: seat.server_url, participant_token: seat.participant_token })}\n`);
|
|
56
|
+
out.write(` listening as ${seat.identity} · ${player.spawnfile}\n`);
|
|
57
|
+
return {
|
|
58
|
+
identity: seat.identity,
|
|
59
|
+
async leave() {
|
|
60
|
+
// Closing its stdin is how the ear is told to leave; a moment later it is made to.
|
|
61
|
+
ear.stdin.end();
|
|
62
|
+
await gone(ear);
|
|
63
|
+
player.stdin.end();
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The seat, knocked for until the room opens. The gateway mints it off the call's snapshot and a
|
|
69
|
+
* simulation asks the moment it has an id — before the worker has joined — so asking once would
|
|
70
|
+
* be asking too early, and joining late is joining after the greeting.
|
|
71
|
+
*/
|
|
72
|
+
export async function aSeatIn(door, call) {
|
|
73
|
+
const deadline = Date.now() + A_ROOM_OPENS_WITHIN_MS;
|
|
74
|
+
for (;;) {
|
|
75
|
+
try {
|
|
76
|
+
return await asked(door, `/v1/calls/${call}/listen`, { method: "POST", body: {} });
|
|
77
|
+
}
|
|
78
|
+
catch (refused) {
|
|
79
|
+
if (Date.now() >= deadline)
|
|
80
|
+
throw refused;
|
|
81
|
+
await new Promise((wake) => setTimeout(wake, A_KNOCK_EVERY_MS));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// The ear beside this file, whatever this file is: `ear.ts` under the loader in a checkout, `ear.js`
|
|
86
|
+
// in the published dist. Which one is read off this module's own name.
|
|
87
|
+
export const EAR = fileURLToPath(new URL(`ear${extname(fileURLToPath(import.meta.url))}`, import.meta.url));
|
|
88
|
+
/** How node runs the ear: through tsx when it is TypeScript, and on its own when it is not. */
|
|
89
|
+
function theLoaderFor(entry) {
|
|
90
|
+
return extname(entry) === ".ts" ? ["--import", "tsx"] : [];
|
|
91
|
+
}
|
|
92
|
+
/** Whether the ear's one dependency is installed here, asked without loading it. */
|
|
93
|
+
function theRoomLibrary() {
|
|
94
|
+
try {
|
|
95
|
+
import.meta.resolve("@livekit/rtc-node");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
throw new Error(NO_ROOM_LIBRARY);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** The ear's exit, or the ear killed when it took too long about it. */
|
|
102
|
+
function gone(ear) {
|
|
103
|
+
return new Promise((left) => {
|
|
104
|
+
const kill = setTimeout(() => ear.kill("SIGKILL"), LEAVING_TAKES_MS);
|
|
105
|
+
ear.once("exit", () => {
|
|
106
|
+
clearTimeout(kill);
|
|
107
|
+
left();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** The first player this machine has on its PATH, started and waiting for samples. */
|
|
112
|
+
function aPlayer() {
|
|
113
|
+
for (const { name, args } of PLAYERS) {
|
|
114
|
+
if (!onThePath(name))
|
|
115
|
+
continue;
|
|
116
|
+
return spawn(name, args, { stdio: ["pipe", "ignore", "ignore"] });
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/** Is this program on this shell's PATH? Asked without starting anything to find out. */
|
|
121
|
+
function onThePath(name) {
|
|
122
|
+
return (process.env["PATH"] ?? "").split(delimiter).some((where) => where !== "" && existsSync(join(where, name)));
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=listening.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listening.js","sourceRoot":"","sources":["../../src/cli/listening.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Loading a tenant's agent file from the CLI: the TypeScript loader, the class, and its own source. */
|
|
2
|
+
import { Agent } from "../agent/agent.js";
|
|
3
|
+
import { type MountOptions } from "../runtime/connect.js";
|
|
4
|
+
/** What the CLI needs to mount or render an agent: the class, and the file it came from. */
|
|
5
|
+
export interface Loaded {
|
|
6
|
+
ctor: new () => Agent;
|
|
7
|
+
file: string;
|
|
8
|
+
source: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Where an agent lives when nobody said. A class whose `render()` returns JSX is written in
|
|
12
|
+
* `agent.tsx`, which is what every example and every generator writes; `agent.ts` still loads, for
|
|
13
|
+
* a class that renders nothing. The first that is there wins, and a usage line names the first.
|
|
14
|
+
*/
|
|
15
|
+
export declare const DEFAULT_AGENTS: readonly ["agent.tsx", "agent.ts"];
|
|
16
|
+
/** Register tsx, once per process: the tenant writes .ts and .tsx and never a build step. */
|
|
17
|
+
export declare function useTypeScript(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Load an agent file: import its default export and hand the class its own source.
|
|
20
|
+
*
|
|
21
|
+
* The source is not a nicety. A class docstring sits ABOVE the class, where `Ctor.toString()`
|
|
22
|
+
* cannot see it, and the parameter types are gone by the time the file is a module — so the identity
|
|
23
|
+
* block would open without its first line and the tools would carry untyped arguments. `describe`
|
|
24
|
+
* is the one call that puts both back, and this is the only place that has the text to give it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function load(file?: string): Promise<Loaded>;
|
|
27
|
+
/**
|
|
28
|
+
* One instance of the loaded class with a line to answer on: what the pages that print a prompt
|
|
29
|
+
* render. A `render()` may read `this.call`, and a page that could not answer that question would
|
|
30
|
+
* be a page about a call that cannot happen.
|
|
31
|
+
*/
|
|
32
|
+
export declare function instanceFor(loaded: Loaded, channel?: string): Agent;
|
|
33
|
+
/** What `mount` is given for a loaded agent: the client, the source and the file it came from. */
|
|
34
|
+
export declare function mountOptions(loaded: Loaded, pc: MountOptions["pc"]): MountOptions;
|
|
35
|
+
/** The refusal for a file typed where a slug is taken, or undefined when it is a slug. */
|
|
36
|
+
export declare function notASlug(said: string | undefined): string | undefined;
|
|
37
|
+
export declare function agentOfThisDirectory(): Promise<string | null>;
|
|
38
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/cli/load.ts"],"names":[],"mappings":"AAAA,wGAAwG;AAMxG,OAAO,EAAE,KAAK,EAAW,MAAM,mBAAmB,CAAC;AAGnD,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,uBAAuB,CAAC;AAGlE,4FAA4F;AAC5F,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,UAAU,KAAK,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,YAAI,WAAW,EAAE,UAAU,CAAU,CAAC;AAIjE,6FAA6F;AAI7F,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAKnD;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAczD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,SAAQ,GAAG,KAAK,CAIlE;AAED,kGAAkG;AAClG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,GAAG,YAAY,CAEjF;AAoBD,0FAA0F;AAC1F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrE;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOnE"}
|