Capture city + LinkedIn on card intake; sharpen the transcription prompt

The card transcription prompt now reads emails/URLs/phones character-by-character,
explicitly forbids autocompleting toward a plausible domain (the mara.com ->
marac.com failure), and emits labeled lines (which also feeds the field extractor
cleaner input).

The extractor gains city + linkedin_url. city is a plain field (low-harm if wrong;
the human sees it on the card). linkedin_url follows the email-integrity rule: kept
only if it literally appears in the source / a revise instruction, never minted -- a
wrong profile URL points at the wrong person. Both flow to the contact via the
existing log-communication upsert (city also syncs to the grid contact pill).

Phone is intentionally NOT included yet: the bot's write path can't store it until a
small server-side change lands (next s9pk). See the matrix-intake guide.
This commit is contained in:
Keysat
2026-06-20 11:07:17 -05:00
parent 5e115a3409
commit 8b2eb01a65
8 changed files with 120 additions and 13 deletions
+14
View File
@@ -54,6 +54,20 @@ def test_interpret_edit_colon_and_alias():
assert payload == ("investor_name", "Acme Capital LLC")
def test_interpret_edit_city_and_linkedin_aliases():
a1, p1 = proposals.interpret_reply("city: New York")
assert (a1, p1) == ("edit", ("city", "New York"))
a2, p2 = proposals.interpret_reply("linkedin=linkedin.com/in/jane")
assert (a2, p2) == ("edit", ("linkedin_url", "linkedin.com/in/jane"))
def test_render_shows_city_and_linkedin_when_present():
p = {**SAMPLE, "city": "New York", "linkedin_url": "linkedin.com/in/jane"}
out = proposals.render(p)
assert "City: New York" in out
assert "LinkedIn: linkedin.com/in/jane" in out
def test_interpret_unknown():
assert proposals.interpret_reply("maybe later")[0] == "unknown"