pinecall-runtime 0.1.6__py3-none-any.whl
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.
- pinecall/__init__.py +0 -0
- pinecall/channels/__init__.py +0 -0
- pinecall/channels/_chooser.py +45 -0
- pinecall/channels/offers.py +219 -0
- pinecall/channels/rooms.py +176 -0
- pinecall/channels/routes.py +275 -0
- pinecall/channels/telephony/__init__.py +0 -0
- pinecall/channels/telephony/_twilio.py +349 -0
- pinecall/channels/telephony/carrier.py +229 -0
- pinecall/channels/telephony/carrier_catalog.py +92 -0
- pinecall/channels/telephony/carriers.csv +41 -0
- pinecall/channels/telephony/dialing.py +419 -0
- pinecall/channels/telephony/firewall.py +58 -0
- pinecall/channels/telephony/hand_over.py +78 -0
- pinecall/channels/telephony/number_path.py +176 -0
- pinecall/channels/telephony/numbers.py +530 -0
- pinecall/channels/telephony/origination.py +77 -0
- pinecall/channels/telephony/sip.py +448 -0
- pinecall/channels/whatsapp.py +413 -0
- pinecall/cli/__init__.py +0 -0
- pinecall/cli/_archive.py +85 -0
- pinecall/cli/_drift.py +38 -0
- pinecall/cli/_facts.py +67 -0
- pinecall/cli/_load.py +433 -0
- pinecall/cli/_operator.py +626 -0
- pinecall/cli/_sessions.py +164 -0
- pinecall/cli/_traceback.py +95 -0
- pinecall/cli/_usage.py +34 -0
- pinecall/cli/main.py +521 -0
- pinecall/domain/__init__.py +0 -0
- pinecall/domain/agent.py +446 -0
- pinecall/domain/call.py +152 -0
- pinecall/domain/country_codes.py +32 -0
- pinecall/domain/errors.py +151 -0
- pinecall/domain/names.py +115 -0
- pinecall/domain/org.py +120 -0
- pinecall/domain/person.py +208 -0
- pinecall/domain/scope.py +21 -0
- pinecall/evals/__init__.py +0 -0
- pinecall/evals/_evidence.py +158 -0
- pinecall/evals/calibration.py +112 -0
- pinecall/evals/callers.py +160 -0
- pinecall/evals/case.py +327 -0
- pinecall/evals/checks.py +437 -0
- pinecall/evals/compliance.py +197 -0
- pinecall/evals/dataset.py +451 -0
- pinecall/evals/goldens.py +331 -0
- pinecall/evals/judges.py +525 -0
- pinecall/evals/runs.py +252 -0
- pinecall/evals/spoken.py +356 -0
- pinecall/fleet/__init__.py +0 -0
- pinecall/fleet/client.py +569 -0
- pinecall/fleet/demand.py +51 -0
- pinecall/fleet/heartbeat.py +194 -0
- pinecall/fleet/measures.py +157 -0
- pinecall/fleet/roster.py +232 -0
- pinecall/fleet/worlds.py +44 -0
- pinecall/gateway/__init__.py +0 -0
- pinecall/gateway/_call_setup.py +53 -0
- pinecall/gateway/_deps.py +556 -0
- pinecall/gateway/_gateway.py +75 -0
- pinecall/gateway/_served.py +396 -0
- pinecall/gateway/_sockets.py +444 -0
- pinecall/gateway/_streams.py +83 -0
- pinecall/gateway/_text_calls.py +182 -0
- pinecall/gateway/api/__init__.py +0 -0
- pinecall/gateway/api/accounts.py +324 -0
- pinecall/gateway/api/agents.py +150 -0
- pinecall/gateway/api/apps.py +478 -0
- pinecall/gateway/api/box.py +658 -0
- pinecall/gateway/api/calibration.py +58 -0
- pinecall/gateway/api/callbacks.py +105 -0
- pinecall/gateway/api/calls.py +655 -0
- pinecall/gateway/api/chat.py +223 -0
- pinecall/gateway/api/dataset.py +163 -0
- pinecall/gateway/api/desk.py +113 -0
- pinecall/gateway/api/entries.py +77 -0
- pinecall/gateway/api/evals.py +647 -0
- pinecall/gateway/api/fleet.py +73 -0
- pinecall/gateway/api/hosting.py +241 -0
- pinecall/gateway/api/judges.py +97 -0
- pinecall/gateway/api/keys.py +110 -0
- pinecall/gateway/api/line.py +142 -0
- pinecall/gateway/api/members.py +197 -0
- pinecall/gateway/api/metrics.py +226 -0
- pinecall/gateway/api/numbers.py +476 -0
- pinecall/gateway/api/ops.py +428 -0
- pinecall/gateway/api/org.py +283 -0
- pinecall/gateway/api/personas.py +157 -0
- pinecall/gateway/api/pipeline.py +206 -0
- pinecall/gateway/api/prompts.py +50 -0
- pinecall/gateway/api/providers.py +240 -0
- pinecall/gateway/api/recordings.py +89 -0
- pinecall/gateway/api/relay.py +169 -0
- pinecall/gateway/api/retrieval.py +403 -0
- pinecall/gateway/api/runner.py +109 -0
- pinecall/gateway/api/sessions.py +102 -0
- pinecall/gateway/api/settings.py +463 -0
- pinecall/gateway/api/signup.py +164 -0
- pinecall/gateway/api/sso_login.py +168 -0
- pinecall/gateway/api/threads.py +187 -0
- pinecall/gateway/api/usage.py +303 -0
- pinecall/gateway/api/visitors.py +222 -0
- pinecall/gateway/api/whatsapp.py +48 -0
- pinecall/gateway/api/widget.py +49 -0
- pinecall/gateway/app.py +504 -0
- pinecall/gateway/calls/__init__.py +0 -0
- pinecall/gateway/calls/binding.py +63 -0
- pinecall/gateway/calls/commands.py +18 -0
- pinecall/gateway/calls/inbox.py +100 -0
- pinecall/gateway/calls/known.py +23 -0
- pinecall/gateway/calls/owners.py +87 -0
- pinecall/gateway/calls/pump.py +33 -0
- pinecall/gateway/calls/serving.py +118 -0
- pinecall/gateway/calls/threads.py +367 -0
- pinecall/gateway/dispatching/__init__.py +0 -0
- pinecall/gateway/dispatching/arrivals.py +58 -0
- pinecall/gateway/dispatching/sweep.py +43 -0
- pinecall/gateway/ending/__init__.py +0 -0
- pinecall/gateway/ending/reaper.py +160 -0
- pinecall/gateway/ending/seal.py +312 -0
- pinecall/gateway/ending/stranded.py +117 -0
- pinecall/log/__init__.py +0 -0
- pinecall/log/_histogram.py +74 -0
- pinecall/log/_relay.py +259 -0
- pinecall/log/_writer.py +454 -0
- pinecall/log/days.py +154 -0
- pinecall/log/drift.py +550 -0
- pinecall/log/facts.py +358 -0
- pinecall/log/inbox.py +169 -0
- pinecall/log/lists.py +155 -0
- pinecall/log/logs.py +581 -0
- pinecall/log/openings.py +71 -0
- pinecall/log/private.py +135 -0
- pinecall/log/queries.py +229 -0
- pinecall/log/readers.py +207 -0
- pinecall/log/reduce.py +659 -0
- pinecall/log/refold.py +217 -0
- pinecall/log/store.py +370 -0
- pinecall/log/usage.py +242 -0
- pinecall/postgres/__init__.py +0 -0
- pinecall/postgres/migrate.py +202 -0
- pinecall/postgres/migrations/0001_schema.sql +591 -0
- pinecall/postgres/migrations/0002_worlds.sql +15 -0
- pinecall/postgres/migrations/0003_lent.sql +4 -0
- pinecall/postgres/migrations/0004_carriers.sql +23 -0
- pinecall/postgres/migrations/0005_retrieved_only.sql +11 -0
- pinecall/postgres/migrations/0006_persona_agents.sql +9 -0
- pinecall/postgres/migrations/0007_money_in_dollars.sql +27 -0
- pinecall/postgres/migrations/0008_lexicon_per_agent.sql +27 -0
- pinecall/postgres/migrations/0009_personas_per_agent.sql +31 -0
- pinecall/postgres/migrations/0010_agent_judges.sql +12 -0
- pinecall/postgres/migrations/0011_erasure.sql +32 -0
- pinecall/postgres/migrations/0012_org_policy.sql +10 -0
- pinecall/postgres/migrations/0013_calling_rules.sql +12 -0
- pinecall/postgres/migrations/0014_consents.sql +24 -0
- pinecall/postgres/migrations/0015_disclosure.sql +7 -0
- pinecall/postgres/migrations/0016_call_records.sql +21 -0
- pinecall/postgres/migrations/0017_reads.sql +17 -0
- pinecall/postgres/migrations/0018_hosting.sql +41 -0
- pinecall/postgres/migrations/0019_hosted_state.sql +10 -0
- pinecall/postgres/migrations/0020_written_once.sql +7 -0
- pinecall/postgres/migrations/0021_hosted_running.sql +21 -0
- pinecall/postgres/migrations/0022_sealed.sql +39 -0
- pinecall/postgres/migrations/0023_usage_totals.sql +158 -0
- pinecall/postgres/migrations/0024_log_key_by_day.sql +8 -0
- pinecall/postgres/migrations/0025_log_before_the_days.sql +15 -0
- pinecall/postgres/migrations/0026_log_before_the_days_validated.sql +4 -0
- pinecall/postgres/migrations/0027_log_by_day.sql +96 -0
- pinecall/postgres/migrations/0030_whatsapp_seen.sql +17 -0
- pinecall/postgres/migrations/0040_reads_widened.sql +15 -0
- pinecall/postgres/migrations/0060_drift.sql +62 -0
- pinecall/postgres/migrations/0061_canaries.sql +24 -0
- pinecall/postgres/migrations/0062_eval_cases.sql +23 -0
- pinecall/postgres/migrations/0063_prompts.sql +16 -0
- pinecall/postgres/migrations/0075_call_private.sql +14 -0
- pinecall/postgres/migrations/0076_recording_keys.sql +13 -0
- pinecall/postgres/migrations/0077_tokens_world.sql +7 -0
- pinecall/postgres/migrations/0078_facts_cost_by_stage.sql +12 -0
- pinecall/postgres/migrations/0079_judge_labels.sql +20 -0
- pinecall/postgres/migrations/0080_call_openings.sql +20 -0
- pinecall/postgres/migrations/0081_seal_lease.sql +7 -0
- pinecall/postgres/migrations/0082_caller_codes.sql +14 -0
- pinecall/postgres/migrations/0083_one_use_words.sql +15 -0
- pinecall/postgres/migrations/0084_knocks_and_run_leases.sql +23 -0
- pinecall/postgres/migrations/0085_seal_lease_holder.sql +8 -0
- pinecall/postgres/migrations/0086_route_origin.sql +17 -0
- pinecall/postgres/migrations/0087_carrier_networks.sql +20 -0
- pinecall/postgres/migrations/0088_route_last_call.sql +3 -0
- pinecall/postgres/migrations/0089_offers.sql +21 -0
- pinecall/postgres/migrations/0090_invitation_purpose.sql +5 -0
- pinecall/postgres/migrations/0091_head_opened_by.sql +6 -0
- pinecall/postgres/migrations/0092_key_parent.sql +6 -0
- pinecall/postgres/migrations/0093_code_tries.sql +10 -0
- pinecall/postgres/migrations/0094_route_approval.sql +12 -0
- pinecall/postgres/migrations/0095_sso_domain_proofs.sql +17 -0
- pinecall/postgres/migrations/0096_row_level_security.sql +38 -0
- pinecall/postgres/migrations/0097_case_status.sql +19 -0
- pinecall/postgres/pool.py +190 -0
- pinecall/process/__init__.py +0 -0
- pinecall/process/_objects.py +97 -0
- pinecall/process/box_settings.py +23 -0
- pinecall/process/connections.py +124 -0
- pinecall/process/metrics.py +127 -0
- pinecall/process/recordings.py +323 -0
- pinecall/process/resolver.py +41 -0
- pinecall/process/sealed_audio.py +173 -0
- pinecall/process/settings.py +534 -0
- pinecall/process/shared.py +158 -0
- pinecall/process/signal.py +416 -0
- pinecall/providers/__init__.py +0 -0
- pinecall/providers/build.py +570 -0
- pinecall/providers/catalog.py +266 -0
- pinecall/providers/credentials.py +230 -0
- pinecall/providers/declared.py +69 -0
- pinecall/providers/prices.py +240 -0
- pinecall/providers/tried.py +104 -0
- pinecall/providers/voices.py +174 -0
- pinecall/public/console/assets/index-BIfKPSgn.js +164 -0
- pinecall/public/console/assets/index-ClOTU-xX.css +1 -0
- pinecall/public/console/favicon.png +0 -0
- pinecall/public/console/index.html +20 -0
- pinecall/public/console/logo-mark.png +0 -0
- pinecall/public/console/pinecall-logo-dark.png +0 -0
- pinecall/public/console/pinecall-logo.png +0 -0
- pinecall/public/console/pinecall-mark.png +0 -0
- pinecall/public/console/sw.js +37 -0
- pinecall/public/widget/pinecall-widget.js +853 -0
- pinecall/py.typed +0 -0
- pinecall/retrieval/__init__.py +0 -0
- pinecall/retrieval/_search.py +186 -0
- pinecall/retrieval/_sections.py +70 -0
- pinecall/retrieval/embed.py +340 -0
- pinecall/retrieval/extraction.py +403 -0
- pinecall/retrieval/knowledge.py +659 -0
- pinecall/retrieval/lookups.py +192 -0
- pinecall/retrieval/memory.py +603 -0
- pinecall/runner/__init__.py +0 -0
- pinecall/runner/_kube.py +459 -0
- pinecall/runner/_plan.py +157 -0
- pinecall/runner/main.py +306 -0
- pinecall/session/__init__.py +0 -0
- pinecall/session/_agent.py +141 -0
- pinecall/session/_hearing.py +101 -0
- pinecall/session/_livekit.py +195 -0
- pinecall/session/_prompt.py +147 -0
- pinecall/session/_recording.py +237 -0
- pinecall/session/call.py +367 -0
- pinecall/session/clock.py +40 -0
- pinecall/session/hold.py +239 -0
- pinecall/session/room.py +626 -0
- pinecall/session/session.py +690 -0
- pinecall/session/text.py +144 -0
- pinecall/session/tools.py +483 -0
- pinecall/session/voice.py +118 -0
- pinecall/session/widget.py +201 -0
- pinecall/tenancy/__init__.py +0 -0
- pinecall/tenancy/admission.py +204 -0
- pinecall/tenancy/agents.py +164 -0
- pinecall/tenancy/canary.py +126 -0
- pinecall/tenancy/carrier_networks.py +156 -0
- pinecall/tenancy/carriers.py +265 -0
- pinecall/tenancy/codes.py +196 -0
- pinecall/tenancy/consents.py +167 -0
- pinecall/tenancy/dial_policy.py +405 -0
- pinecall/tenancy/disclosure.py +41 -0
- pinecall/tenancy/erasure.py +204 -0
- pinecall/tenancy/export.py +167 -0
- pinecall/tenancy/hosted_running.py +166 -0
- pinecall/tenancy/hosting.py +475 -0
- pinecall/tenancy/judges.py +126 -0
- pinecall/tenancy/keys.py +467 -0
- pinecall/tenancy/knocks.py +40 -0
- pinecall/tenancy/letters.py +378 -0
- pinecall/tenancy/mail.py +458 -0
- pinecall/tenancy/org_secrets.py +123 -0
- pinecall/tenancy/orgs.py +78 -0
- pinecall/tenancy/people.py +543 -0
- pinecall/tenancy/personas.py +145 -0
- pinecall/tenancy/policy.py +65 -0
- pinecall/tenancy/prompts.py +48 -0
- pinecall/tenancy/reads.py +73 -0
- pinecall/tenancy/recording_keys.py +41 -0
- pinecall/tenancy/remembered.py +148 -0
- pinecall/tenancy/retention.py +86 -0
- pinecall/tenancy/scopes.py +406 -0
- pinecall/tenancy/signin.py +622 -0
- pinecall/tenancy/spend.py +69 -0
- pinecall/tenancy/sso.py +431 -0
- pinecall/tenancy/sso_domains.py +132 -0
- pinecall/tenancy/throttle.py +88 -0
- pinecall/tenancy/tokens.py +400 -0
- pinecall/tenancy/traceback.py +70 -0
- pinecall/tenancy/usage.py +136 -0
- pinecall/tenancy/vault.py +204 -0
- pinecall/tenancy/words.py +144 -0
- pinecall/wire/__init__.py +0 -0
- pinecall/wire/commands.py +350 -0
- pinecall/wire/events.py +655 -0
- pinecall/wire/frames.py +65 -0
- pinecall/wire/metrics.py +287 -0
- pinecall/wire/parts.py +320 -0
- pinecall/wire/rest/__init__.py +0 -0
- pinecall/wire/rest/accounts.py +512 -0
- pinecall/wire/rest/agents.py +172 -0
- pinecall/wire/rest/calls.py +397 -0
- pinecall/wire/rest/evals.py +453 -0
- pinecall/wire/rest/fleet.py +69 -0
- pinecall/wire/rest/hosting.py +174 -0
- pinecall/wire/rest/numbers.py +280 -0
- pinecall/wire/rest/ops.py +342 -0
- pinecall/wire/rest/providers.py +83 -0
- pinecall/wire/rest/retrieval.py +301 -0
- pinecall/wire/rest/settings.py +184 -0
- pinecall/wire/rest/usage.py +245 -0
- pinecall/wire/room.py +61 -0
- pinecall/wire/scores.py +49 -0
- pinecall/wire/state.py +243 -0
- pinecall/worker/__init__.py +0 -0
- pinecall/worker/_job.py +655 -0
- pinecall/worker/_recorder.py +82 -0
- pinecall/worker/_traces.py +48 -0
- pinecall/worker/main.py +307 -0
- pinecall_runtime-0.1.6.dist-info/METADATA +212 -0
- pinecall_runtime-0.1.6.dist-info/RECORD +328 -0
- pinecall_runtime-0.1.6.dist-info/WHEEL +4 -0
- pinecall_runtime-0.1.6.dist-info/entry_points.txt +2 -0
- pinecall_runtime-0.1.6.dist-info/licenses/LICENSE +202 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"""The bodies of the knowledge and memory doors."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from pinecall.domain.names import Channel
|
|
6
|
+
from pinecall.wire.frames import WireModel
|
|
7
|
+
from pinecall.wire.parts import (
|
|
8
|
+
KnowledgeFile,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
# ── knowledge bases ──
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# The base is replaced whole, never merged.
|
|
15
|
+
class KnowledgePush(WireModel):
|
|
16
|
+
"""PUT /v1/knowledge/{base}, the body: the tenant's folder as of now."""
|
|
17
|
+
|
|
18
|
+
files: list[KnowledgeFile]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class KnowledgePushed(WireModel):
|
|
22
|
+
"""PUT /v1/knowledge/{base}, the answer: the base, the chunks it became, how long it took."""
|
|
23
|
+
|
|
24
|
+
base: str
|
|
25
|
+
chunks: int
|
|
26
|
+
took_ms: float
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class KnowledgeBase(WireModel):
|
|
30
|
+
"""One base as the list draws it: its size, the model that wrote it, when it was pushed."""
|
|
31
|
+
|
|
32
|
+
base: str
|
|
33
|
+
chunks: int
|
|
34
|
+
model: str
|
|
35
|
+
pushed_at: float
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class KnowledgeList(WireModel):
|
|
39
|
+
"""GET /v1/knowledge: every base the key's scope reads."""
|
|
40
|
+
|
|
41
|
+
bases: list[KnowledgeBase]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class KnowledgeUse(WireModel):
|
|
45
|
+
"""One base and the agents whose settings attach it."""
|
|
46
|
+
|
|
47
|
+
base: str
|
|
48
|
+
agents: list[str]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class KnowledgeUses(WireModel):
|
|
52
|
+
"""GET /v1/knowledge/attached: which agents read each base, off their newest settings."""
|
|
53
|
+
|
|
54
|
+
bases: list[KnowledgeUse]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class KnowledgeFileRow(WireModel):
|
|
58
|
+
"""One file of a base as the list draws it."""
|
|
59
|
+
|
|
60
|
+
path: str
|
|
61
|
+
chars: int
|
|
62
|
+
chunks: int
|
|
63
|
+
pushed_at: float
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# `kept` is false for a base whose files were never stored, only its chunks.
|
|
67
|
+
class KnowledgeFiles(WireModel):
|
|
68
|
+
"""GET /v1/knowledge/{base}: every file of the base, never its text."""
|
|
69
|
+
|
|
70
|
+
base: str
|
|
71
|
+
kept: bool
|
|
72
|
+
files: list[KnowledgeFileRow]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class KnowledgeFileRead(WireModel):
|
|
76
|
+
"""GET /v1/knowledge/{base}/files/{path}: one file, text and all."""
|
|
77
|
+
|
|
78
|
+
path: str
|
|
79
|
+
text: str
|
|
80
|
+
chunks: int
|
|
81
|
+
pushed_at: float
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class KnowledgeFilePut(WireModel):
|
|
85
|
+
"""PUT /v1/knowledge/{base}/files/{path}, the body: the file's whole text."""
|
|
86
|
+
|
|
87
|
+
text: str
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class KnowledgeFilePushed(WireModel):
|
|
91
|
+
"""PUT /v1/knowledge/{base}/files/{path}, the answer: the file, its chunks, how long it took."""
|
|
92
|
+
|
|
93
|
+
base: str
|
|
94
|
+
path: str
|
|
95
|
+
chunks: int
|
|
96
|
+
took_ms: float
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
# A chunk answers when its file and heading path start with `expects`, never by substring.
|
|
100
|
+
class GoldenQuestion(WireModel):
|
|
101
|
+
"""One question of a base's golden: what somebody asks, and the chunk that should answer."""
|
|
102
|
+
|
|
103
|
+
asks: str
|
|
104
|
+
expects: str
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class KnowledgeGolden(WireModel):
|
|
108
|
+
"""POST /v1/knowledge/{base}/eval, the body: the questions a base is held to."""
|
|
109
|
+
|
|
110
|
+
questions: list[GoldenQuestion]
|
|
111
|
+
k: int | None = None
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class GoldenMiss(WireModel):
|
|
115
|
+
"""One question whose chunk was not among the k returned, and what came back instead."""
|
|
116
|
+
|
|
117
|
+
asks: str
|
|
118
|
+
expects: str
|
|
119
|
+
found: list[str]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class KnowledgeScore(WireModel):
|
|
123
|
+
"""POST /v1/knowledge/{base}/eval, the answer: recall@k and nDCG@10, computed with no model."""
|
|
124
|
+
|
|
125
|
+
base: str
|
|
126
|
+
model: str
|
|
127
|
+
questions: int
|
|
128
|
+
k: int
|
|
129
|
+
recall_at_k: float
|
|
130
|
+
ndcg_at_10: float
|
|
131
|
+
took_ms: float
|
|
132
|
+
misses: list[GoldenMiss]
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# ── memory ──
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# A fact is never updated, only superseded, so the history keeps every version.
|
|
139
|
+
class ContactFact(WireModel):
|
|
140
|
+
"""One fact of a contact's history, with the two dates that bound it."""
|
|
141
|
+
|
|
142
|
+
id: str | None = None
|
|
143
|
+
text: str
|
|
144
|
+
category: str | None = None
|
|
145
|
+
source: str | None = None
|
|
146
|
+
valid_from: float
|
|
147
|
+
invalidated_at: float | None
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class ContactMemory(WireModel):
|
|
151
|
+
"""GET /v1/contacts/{contact}/memory: every fact ever kept of the contact, current first."""
|
|
152
|
+
|
|
153
|
+
facts: list[ContactFact]
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class Forgotten(WireModel):
|
|
157
|
+
"""DELETE /v1/contacts/{contact}/memory and /v1/memory/facts/{id}: how many facts went."""
|
|
158
|
+
|
|
159
|
+
forgotten: int
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class AgentFact(WireModel):
|
|
163
|
+
"""One current fact, among the contacts an agent's calls taught."""
|
|
164
|
+
|
|
165
|
+
id: str
|
|
166
|
+
contact: str
|
|
167
|
+
text: str
|
|
168
|
+
category: str | None
|
|
169
|
+
written_at: float
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class AgentMemory(WireModel):
|
|
173
|
+
"""GET /v1/agents/{slug}/memory: the facts the agent's calls taught, newest first, a page."""
|
|
174
|
+
|
|
175
|
+
facts: list[AgentFact]
|
|
176
|
+
next: str | None
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class OrgFact(WireModel):
|
|
180
|
+
"""One current fact of the org, with the agent whose call taught it."""
|
|
181
|
+
|
|
182
|
+
id: str
|
|
183
|
+
agent: str
|
|
184
|
+
contact: str
|
|
185
|
+
text: str
|
|
186
|
+
category: str | None
|
|
187
|
+
written_at: float
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class OrgMemory(WireModel):
|
|
191
|
+
"""GET /v1/memory: the org's current facts from every agent, newest first, a page."""
|
|
192
|
+
|
|
193
|
+
facts: list[OrgFact]
|
|
194
|
+
next: str | None = None
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
# A question brings its own facts: written to a scratch contact, asked, and forgotten.
|
|
198
|
+
class MemoryQuestion(WireModel):
|
|
199
|
+
"""One question of a memory golden: what memory holds, what is asked, what should come back."""
|
|
200
|
+
|
|
201
|
+
holds: list[str]
|
|
202
|
+
asks: str
|
|
203
|
+
expects: list[str]
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class MemoryGolden(WireModel):
|
|
207
|
+
"""POST /v1/contacts/memory/eval, the body: the questions memory is held to."""
|
|
208
|
+
|
|
209
|
+
questions: list[MemoryQuestion]
|
|
210
|
+
k: int | None = None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class MemoryMiss(WireModel):
|
|
214
|
+
"""One question memory did not answer whole: what it missed, and what came back instead."""
|
|
215
|
+
|
|
216
|
+
asks: str
|
|
217
|
+
missing: list[str]
|
|
218
|
+
found: list[str]
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class MemoryScore(WireModel):
|
|
222
|
+
"""POST /v1/contacts/memory/eval, the answer: recall@k and nDCG@10, computed with no model."""
|
|
223
|
+
|
|
224
|
+
model: str
|
|
225
|
+
questions: int
|
|
226
|
+
k: int
|
|
227
|
+
recall_at_k: float
|
|
228
|
+
ndcg_at_10: float
|
|
229
|
+
took_ms: float
|
|
230
|
+
misses: list[MemoryMiss]
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# A category is the agent's own word, a value is a literal the caller said, a supersession an id:
|
|
234
|
+
# nothing is judged by comparing two sentences.
|
|
235
|
+
class ExtractionExpected(WireModel):
|
|
236
|
+
"""What must come of one call's hang-up."""
|
|
237
|
+
|
|
238
|
+
writes: list[str] = Field(default_factory=list[str])
|
|
239
|
+
never: list[str] = Field(default_factory=list[str])
|
|
240
|
+
never_says: list[str] = Field(default_factory=list[str])
|
|
241
|
+
invalidates: list[str] = Field(default_factory=list[str])
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class ExtractionGolden(WireModel):
|
|
245
|
+
"""One call written down, what memory holds before it, and what memory must make of it."""
|
|
246
|
+
|
|
247
|
+
name: str
|
|
248
|
+
said: list[tuple[str, str]]
|
|
249
|
+
holds: list[str] = Field(default_factory=list[str])
|
|
250
|
+
plants: list[str] = Field(default_factory=list[str])
|
|
251
|
+
channel: Channel = "phone"
|
|
252
|
+
expect: ExtractionExpected = Field(default_factory=ExtractionExpected)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
class ExtractionCases(WireModel):
|
|
256
|
+
"""POST /v1/agents/{slug}/memory/extraction, the body: one model call per case."""
|
|
257
|
+
|
|
258
|
+
# Fifty model calls in one request at most, on keys the box may lend.
|
|
259
|
+
cases: list[ExtractionGolden] = Field(max_length=50)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
class ExtractionBroke(WireModel):
|
|
263
|
+
"""One check a case did not hold, and the evidence in a sentence."""
|
|
264
|
+
|
|
265
|
+
check: str
|
|
266
|
+
detail: str
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
class ExtractionJudged(WireModel):
|
|
270
|
+
"""One case run: what memory would have kept, what admission refused, what did not hold."""
|
|
271
|
+
|
|
272
|
+
name: str
|
|
273
|
+
held: bool
|
|
274
|
+
wrote: list[str] = Field(default_factory=list[str])
|
|
275
|
+
refused: list[str] = Field(default_factory=list[str])
|
|
276
|
+
broke: list[ExtractionBroke] = Field(default_factory=list[ExtractionBroke])
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class ExtractionRun(WireModel):
|
|
280
|
+
"""POST /v1/agents/{slug}/memory/extraction, the answer: the model, how many held, each case."""
|
|
281
|
+
|
|
282
|
+
agent: str
|
|
283
|
+
model: str
|
|
284
|
+
cases: int
|
|
285
|
+
held: int
|
|
286
|
+
took_ms: float
|
|
287
|
+
results: list[ExtractionJudged]
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class FoundChunk(WireModel):
|
|
291
|
+
"""One chunk a search found: the file it came from, the heading it sits under, its body."""
|
|
292
|
+
|
|
293
|
+
path: str
|
|
294
|
+
heading: str | None
|
|
295
|
+
text: str
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class SearchFound(WireModel):
|
|
299
|
+
"""What search answers a call and an app's `this.knowledge.search`: the best chunks first."""
|
|
300
|
+
|
|
301
|
+
chunks: list[FoundChunk]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""The bodies of the settings doors: an agent's tuning and lexicon, versioned, and its canary."""
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from pinecall.domain.names import Env
|
|
6
|
+
from pinecall.wire.frames import WireModel
|
|
7
|
+
from pinecall.wire.parts import (
|
|
8
|
+
DocsConfig,
|
|
9
|
+
GreetingConfig,
|
|
10
|
+
HangupConfig,
|
|
11
|
+
MemoryConfig,
|
|
12
|
+
Pronunciation,
|
|
13
|
+
TurnConfig,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Every field is optional: one left out is not set, and the runtime's own default stands for it.
|
|
18
|
+
class SettingsBody(WireModel):
|
|
19
|
+
"""An agent's settings as the org set them, per world and per scope."""
|
|
20
|
+
|
|
21
|
+
voice: str | None = None
|
|
22
|
+
tts: str | None = None
|
|
23
|
+
tts_model: str | None = None
|
|
24
|
+
stt: str | None = None
|
|
25
|
+
llm: str | None = None
|
|
26
|
+
language: str | None = None
|
|
27
|
+
greeting: GreetingConfig | None = None
|
|
28
|
+
hangup: HangupConfig | None = None
|
|
29
|
+
turn: TurnConfig | None = None
|
|
30
|
+
memory: MemoryConfig | None = None
|
|
31
|
+
record: bool | None = None
|
|
32
|
+
max_duration_s: int | None = None
|
|
33
|
+
llm_timeout_s: float | None = None
|
|
34
|
+
knowledge: str | None = None
|
|
35
|
+
bases: list[DocsConfig] | None = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SettingsRow(WireModel):
|
|
39
|
+
"""One kept version of an agent's settings: whose scope, which version, by whom, what."""
|
|
40
|
+
|
|
41
|
+
holder: str
|
|
42
|
+
version: int
|
|
43
|
+
author: str
|
|
44
|
+
note: str | None
|
|
45
|
+
set_at: float
|
|
46
|
+
config: SettingsBody
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class SettingsResponse(WireModel):
|
|
50
|
+
"""GET /v1/agents/{slug}/settings: yours, the team's and production's newest, or null."""
|
|
51
|
+
|
|
52
|
+
world: Env
|
|
53
|
+
yours: SettingsRow | None
|
|
54
|
+
team: SettingsRow | None
|
|
55
|
+
production: SettingsRow | None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class PutSettingsRequest(WireModel):
|
|
59
|
+
"""PUT /v1/agents/{slug}/settings: the whole set, the version read, why, whose scope."""
|
|
60
|
+
|
|
61
|
+
config: SettingsBody
|
|
62
|
+
if_version: int | None = None
|
|
63
|
+
note: str | None = None
|
|
64
|
+
team: bool = False
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class HistoryQuery(WireModel):
|
|
68
|
+
"""The query string of a history: whose scope, and how many versions at most."""
|
|
69
|
+
|
|
70
|
+
team: bool = False
|
|
71
|
+
limit: int = Field(default=20, ge=1, le=200)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class SettingsHistoryResponse(WireModel):
|
|
75
|
+
"""GET /v1/agents/{slug}/settings/history: one scope's versions, newest first."""
|
|
76
|
+
|
|
77
|
+
world: Env
|
|
78
|
+
holder: str
|
|
79
|
+
rows: list[SettingsRow]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class SettingsDiffResponse(WireModel):
|
|
83
|
+
"""GET /v1/agents/{slug}/settings/diff: this scope's newest against another's, by field."""
|
|
84
|
+
|
|
85
|
+
ours: SettingsRow | None
|
|
86
|
+
theirs: SettingsRow | None
|
|
87
|
+
changed: list[str]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RollbackSettingsRequest(WireModel):
|
|
91
|
+
"""POST /v1/agents/{slug}/settings/rollback: the version to bring back, as a new one."""
|
|
92
|
+
|
|
93
|
+
version: int
|
|
94
|
+
team: bool = False
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# A share is whole percents: 0 keeps the version off every call without clearing the canary.
|
|
98
|
+
class PutCanaryRequest(WireModel):
|
|
99
|
+
"""PUT /v1/agents/{slug}/settings/canary: the version, its share of the calls, why, whose."""
|
|
100
|
+
|
|
101
|
+
version: int = Field(ge=1)
|
|
102
|
+
share: int = Field(ge=0, le=100)
|
|
103
|
+
note: str | None = None
|
|
104
|
+
team: bool = False
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class CanaryQuery(WireModel):
|
|
108
|
+
"""The query string of a canary's read or clearing: whose scope."""
|
|
109
|
+
|
|
110
|
+
team: bool = False
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class CanaryRow(WireModel):
|
|
114
|
+
"""The canary a scope stands on: which version takes how many calls in a hundred, by whom."""
|
|
115
|
+
|
|
116
|
+
holder: str
|
|
117
|
+
version: int
|
|
118
|
+
share: int
|
|
119
|
+
author: str
|
|
120
|
+
note: str | None
|
|
121
|
+
set_at: float
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class CanaryResponse(WireModel):
|
|
125
|
+
"""GET, PUT and DELETE /v1/agents/{slug}/settings/canary: the scope's canary, or null."""
|
|
126
|
+
|
|
127
|
+
world: Env
|
|
128
|
+
holder: str
|
|
129
|
+
canary: CanaryRow | None
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class LexiconBody(WireModel):
|
|
133
|
+
"""The agent's lexicon: how the voice says its words, and the words the ears must know."""
|
|
134
|
+
|
|
135
|
+
said: list[Pronunciation]
|
|
136
|
+
heard: list[str]
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class LexiconRow(WireModel):
|
|
140
|
+
"""One kept version of the agent's lexicon."""
|
|
141
|
+
|
|
142
|
+
holder: str
|
|
143
|
+
version: int
|
|
144
|
+
author: str
|
|
145
|
+
note: str | None
|
|
146
|
+
set_at: float
|
|
147
|
+
lexicon: LexiconBody
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class LexiconResponse(WireModel):
|
|
151
|
+
"""GET /v1/agents/{slug}/lexicon: yours, the team's and production's newest, or null."""
|
|
152
|
+
|
|
153
|
+
world: Env
|
|
154
|
+
yours: LexiconRow | None
|
|
155
|
+
team: LexiconRow | None
|
|
156
|
+
production: LexiconRow | None
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class PutLexiconRequest(WireModel):
|
|
160
|
+
"""PUT /v1/agents/{slug}/lexicon: the whole lexicon, the version read, why, whose scope."""
|
|
161
|
+
|
|
162
|
+
lexicon: LexiconBody
|
|
163
|
+
if_version: int | None = None
|
|
164
|
+
note: str | None = None
|
|
165
|
+
team: bool = False
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class LexiconHistoryResponse(WireModel):
|
|
169
|
+
"""GET /v1/agents/{slug}/lexicon/history: one scope's versions, newest first."""
|
|
170
|
+
|
|
171
|
+
world: Env
|
|
172
|
+
holder: str
|
|
173
|
+
rows: list[LexiconRow]
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class CallSettingsResponse(WireModel):
|
|
177
|
+
"""GET /v1/calls/{call}/settings: the tuning and lexicon the call was built on."""
|
|
178
|
+
|
|
179
|
+
config_version: int | None
|
|
180
|
+
lexicon_version: int | None
|
|
181
|
+
config: SettingsRow | None
|
|
182
|
+
lexicon: LexiconRow | None
|
|
183
|
+
# The call ran a canary's version, picked for its share of the calls.
|
|
184
|
+
canary: bool = False
|