@diegoaltoworks/talker 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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +299 -0
  3. package/dist/adapters/twilio.d.ts +12 -0
  4. package/dist/adapters/twilio.d.ts.map +1 -0
  5. package/dist/core/chat.d.ts +14 -0
  6. package/dist/core/chat.d.ts.map +1 -0
  7. package/dist/core/chatbot/client.d.ts +12 -0
  8. package/dist/core/chatbot/client.d.ts.map +1 -0
  9. package/dist/core/chatbot/conversations.d.ts +14 -0
  10. package/dist/core/chatbot/conversations.d.ts.map +1 -0
  11. package/dist/core/chatbot/index.d.ts +9 -0
  12. package/dist/core/chatbot/index.d.ts.map +1 -0
  13. package/dist/core/chatbot/types.d.ts +25 -0
  14. package/dist/core/chatbot/types.d.ts.map +1 -0
  15. package/dist/core/context.d.ts +61 -0
  16. package/dist/core/context.d.ts.map +1 -0
  17. package/dist/core/context.test.d.ts +2 -0
  18. package/dist/core/context.test.d.ts.map +1 -0
  19. package/dist/core/errors.d.ts +8 -0
  20. package/dist/core/errors.d.ts.map +1 -0
  21. package/dist/core/errors.test.d.ts +2 -0
  22. package/dist/core/errors.test.d.ts.map +1 -0
  23. package/dist/core/logger.d.ts +11 -0
  24. package/dist/core/logger.d.ts.map +1 -0
  25. package/dist/core/phrases.d.ts +30 -0
  26. package/dist/core/phrases.d.ts.map +1 -0
  27. package/dist/core/phrases.test.d.ts +2 -0
  28. package/dist/core/phrases.test.d.ts.map +1 -0
  29. package/dist/core/processing/incoming.d.ts +12 -0
  30. package/dist/core/processing/incoming.d.ts.map +1 -0
  31. package/dist/core/processing/index.d.ts +10 -0
  32. package/dist/core/processing/index.d.ts.map +1 -0
  33. package/dist/core/processing/openai.d.ts +15 -0
  34. package/dist/core/processing/openai.d.ts.map +1 -0
  35. package/dist/core/processing/outgoing.d.ts +12 -0
  36. package/dist/core/processing/outgoing.d.ts.map +1 -0
  37. package/dist/core/processing/prompts.d.ts +14 -0
  38. package/dist/core/processing/prompts.d.ts.map +1 -0
  39. package/dist/core/twiml.d.ts +31 -0
  40. package/dist/core/twiml.d.ts.map +1 -0
  41. package/dist/core/twiml.test.d.ts +2 -0
  42. package/dist/core/twiml.test.d.ts.map +1 -0
  43. package/dist/core/voice.d.ts +16 -0
  44. package/dist/core/voice.d.ts.map +1 -0
  45. package/dist/core/voice.test.d.ts +2 -0
  46. package/dist/core/voice.test.d.ts.map +1 -0
  47. package/dist/core/xml.d.ts +8 -0
  48. package/dist/core/xml.d.ts.map +1 -0
  49. package/dist/core/xml.test.d.ts +2 -0
  50. package/dist/core/xml.test.d.ts.map +1 -0
  51. package/dist/db/client.d.ts +25 -0
  52. package/dist/db/client.d.ts.map +1 -0
  53. package/dist/db/index.d.ts +12 -0
  54. package/dist/db/index.d.ts.map +1 -0
  55. package/dist/db/migrate.d.ts +8 -0
  56. package/dist/db/migrate.d.ts.map +1 -0
  57. package/dist/db/persist.d.ts +18 -0
  58. package/dist/db/persist.d.ts.map +1 -0
  59. package/dist/db/sessions.d.ts +57 -0
  60. package/dist/db/sessions.d.ts.map +1 -0
  61. package/dist/flows/index.d.ts +12 -0
  62. package/dist/flows/index.d.ts.map +1 -0
  63. package/dist/flows/intent.d.ts +11 -0
  64. package/dist/flows/intent.d.ts.map +1 -0
  65. package/dist/flows/loader.d.ts +12 -0
  66. package/dist/flows/loader.d.ts.map +1 -0
  67. package/dist/flows/manager.d.ts +14 -0
  68. package/dist/flows/manager.d.ts.map +1 -0
  69. package/dist/flows/params.d.ts +12 -0
  70. package/dist/flows/params.d.ts.map +1 -0
  71. package/dist/flows/registry.d.ts +35 -0
  72. package/dist/flows/registry.d.ts.map +1 -0
  73. package/dist/flows/utils.d.ts +12 -0
  74. package/dist/flows/utils.d.ts.map +1 -0
  75. package/dist/flows/utils.test.d.ts +2 -0
  76. package/dist/flows/utils.test.d.ts.map +1 -0
  77. package/dist/index.d.ts +62 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +1840 -0
  80. package/dist/index.mjs +1771 -0
  81. package/dist/plugin.d.ts +31 -0
  82. package/dist/plugin.d.ts.map +1 -0
  83. package/dist/routes/call/handle-answer.d.ts +10 -0
  84. package/dist/routes/call/handle-answer.d.ts.map +1 -0
  85. package/dist/routes/call/handle-initial.d.ts +10 -0
  86. package/dist/routes/call/handle-initial.d.ts.map +1 -0
  87. package/dist/routes/call/handle-nospeech.d.ts +10 -0
  88. package/dist/routes/call/handle-nospeech.d.ts.map +1 -0
  89. package/dist/routes/call/handle-respond.d.ts +11 -0
  90. package/dist/routes/call/handle-respond.d.ts.map +1 -0
  91. package/dist/routes/call/handle-status.d.ts +9 -0
  92. package/dist/routes/call/handle-status.d.ts.map +1 -0
  93. package/dist/routes/call/index.d.ts +14 -0
  94. package/dist/routes/call/index.d.ts.map +1 -0
  95. package/dist/routes/call/pending.d.ts +20 -0
  96. package/dist/routes/call/pending.d.ts.map +1 -0
  97. package/dist/routes/call/processor.d.ts +13 -0
  98. package/dist/routes/call/processor.d.ts.map +1 -0
  99. package/dist/routes/sms/handle-incoming.d.ts +10 -0
  100. package/dist/routes/sms/handle-incoming.d.ts.map +1 -0
  101. package/dist/routes/sms/index.d.ts +13 -0
  102. package/dist/routes/sms/index.d.ts.map +1 -0
  103. package/dist/routes/sms/processor.d.ts +12 -0
  104. package/dist/routes/sms/processor.d.ts.map +1 -0
  105. package/dist/standalone.d.ts +44 -0
  106. package/dist/standalone.d.ts.map +1 -0
  107. package/dist/types.d.ts +240 -0
  108. package/dist/types.d.ts.map +1 -0
  109. package/language/de.json +27 -0
  110. package/language/en.json +27 -0
  111. package/language/es.json +27 -0
  112. package/language/fr.json +27 -0
  113. package/language/nl.json +27 -0
  114. package/language/pt.json +27 -0
  115. package/package.json +103 -0
  116. package/prompts/incoming.md +88 -0
  117. package/prompts/outgoing.md +58 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "greeting": "Hallo! Ik ben uw spraakassistent. Hoe kan ik u helpen vandaag?",
3
+ "didNotCatch": "Ik heb dat niet verstaan. Kunt u het herhalen?",
4
+ "didNotHear": "Ik heb niets gehoord. Tot ziens.",
5
+ "didNotHearRetry": "Sorry, ik heb dat niet verstaan. Kunt u het nog een keer proberen?",
6
+ "didNotHearFinal": "Het spijt me echt maar ik kan niet horen wat u zegt. Bel alstublieft opnieuw. Tot snel.",
7
+ "transfer": "Geen probleem, ik verbind u door.",
8
+ "acknowledgment": "Een moment alstublieft.",
9
+ "farewell": {
10
+ "morning": "Graag gedaan! Fijne dag nog. Tot ziens!",
11
+ "afternoon": "Graag gedaan! Fijne middag nog. Tot ziens!",
12
+ "evening": "Graag gedaan! Fijne avond nog. Tot ziens!"
13
+ },
14
+ "error": "Sorry, er is een fout opgetreden. Probeer het later opnieuw. Tot ziens.",
15
+ "timeout": "Sorry, ik deed er te lang over om te antwoorden. Probeer het opnieuw. Tot ziens.",
16
+ "lostQuestion": "Sorry, ik ben uw vraag kwijt. Kunt u het herhalen?",
17
+ "flow": {
18
+ "cancelled": "Geen probleem! Ik heb dat geannuleerd. Waarmee kan ik je helpen?"
19
+ },
20
+ "sms": {
21
+ "greeting": "Hallo! Ik ben uw spraakassistent. Hoe kan ik u helpen?",
22
+ "greetingShort": "Hallo! Stuur me uw vraag!",
23
+ "callForHelp": "Voor complexe vragen, bel ons direct.",
24
+ "processingError": "Ik heb moeite om dat te verwerken. Probeer het opnieuw of bel ons.",
25
+ "genericError": "Sorry, er ging iets mis. Probeer het opnieuw."
26
+ }
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "greeting": "Ola! Sou seu assistente de voz. Como posso ajuda-lo hoje?",
3
+ "didNotCatch": "Nao entendi isso. Voce poderia repetir, por favor?",
4
+ "didNotHear": "Nao ouvi nada. Tchau!",
5
+ "didNotHearRetry": "Desculpe, nao entendi isso. Voce poderia tentar novamente?",
6
+ "didNotHearFinal": "Sinto muito mas nao consigo ouvir o que voce esta dizendo. Por favor, ligue novamente. Ate logo.",
7
+ "transfer": "Sem problema, vou transferi-lo agora.",
8
+ "acknowledgment": "Um momento, por favor.",
9
+ "farewell": {
10
+ "morning": "De nada! Tenha um otimo dia. Tchau!",
11
+ "afternoon": "De nada! Tenha uma otima tarde. Tchau!",
12
+ "evening": "De nada! Tenha uma otima noite. Tchau!"
13
+ },
14
+ "error": "Desculpe, encontrei um erro. Por favor, tente novamente mais tarde. Tchau!",
15
+ "timeout": "Desculpe, demorei muito para responder. Por favor, tente novamente. Tchau!",
16
+ "lostQuestion": "Desculpe, perdi o fio da sua pergunta. Voce poderia repetir?",
17
+ "flow": {
18
+ "cancelled": "Sem problema! Cancelei isso. Como posso ajudar?"
19
+ },
20
+ "sms": {
21
+ "greeting": "Ola! Sou seu assistente de voz. Como posso ajuda-lo?",
22
+ "greetingShort": "Ola! Envie-me sua pergunta!",
23
+ "callForHelp": "Para questoes complexas, ligue diretamente.",
24
+ "processingError": "Estou tendo dificuldades para processar isso. Por favor, tente novamente ou nos ligue.",
25
+ "genericError": "Desculpe, algo deu errado. Por favor, tente novamente."
26
+ }
27
+ }
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "@diegoaltoworks/talker",
3
+ "version": "0.1.0",
4
+ "description": "Telephony plugin for Chatter — adds voice call and SMS support via Twilio",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ },
14
+ "./twilio": {
15
+ "types": "./dist/adapters/twilio.d.ts",
16
+ "import": "./dist/adapters/twilio.mjs",
17
+ "require": "./dist/adapters/twilio.js"
18
+ }
19
+ },
20
+ "files": ["dist", "prompts", "language", "README.md", "LICENSE"],
21
+ "scripts": {
22
+ "dev": "bun --watch src/index.ts",
23
+ "build": "bun run build:clean && bun run build:types && bun run build:esm && bun run build:cjs",
24
+ "build:clean": "rm -rf dist",
25
+ "build:types": "tsc --emitDeclarationOnly --outDir dist",
26
+ "build:esm": "esbuild src/index.ts --bundle --format=esm --outfile=dist/index.mjs --external:hono --external:openai --external:@diegoaltoworks/chatter --external:@libsql/client --platform=node --target=node18",
27
+ "build:cjs": "esbuild src/index.ts --bundle --format=cjs --outfile=dist/index.js --external:hono --external:openai --external:@diegoaltoworks/chatter --external:@libsql/client --platform=node --target=node18",
28
+ "test": "bun test",
29
+ "test:unit": "bun test src/**/*.test.ts",
30
+ "test:integration": "bun test test/integration/**/*.test.ts",
31
+ "test:watch": "bun test --watch",
32
+ "test:coverage": "bun test --coverage",
33
+ "typecheck": "tsc --noEmit",
34
+ "lint": "biome check .",
35
+ "lint:fix": "biome check --write .",
36
+ "format": "biome format --write .",
37
+ "security:audit": "bun audit",
38
+ "security:audit:fix": "bun update",
39
+ "security:check": "bun audit --audit-level=moderate",
40
+ "check": "bun run typecheck && bun run lint && bun run test && bun run security:check",
41
+ "prepublishOnly": "bun run lint && bun run typecheck && bun run test && bun run security:check && bun run build",
42
+ "prepare": "husky || true"
43
+ },
44
+ "keywords": [
45
+ "telephony",
46
+ "twilio",
47
+ "voice",
48
+ "sms",
49
+ "chatbot",
50
+ "chatter",
51
+ "twiml",
52
+ "conversational-ai",
53
+ "ivr",
54
+ "phone"
55
+ ],
56
+ "author": "Diego Alto <diego@diegoalto.works>",
57
+ "license": "MIT",
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "https://github.com/diegoaltoworks/talker.git"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/diegoaltoworks/talker/issues"
64
+ },
65
+ "homepage": "https://github.com/diegoaltoworks/talker#readme",
66
+ "engines": {
67
+ "node": ">=18.0.0"
68
+ },
69
+ "peerDependencies": {
70
+ "@diegoaltoworks/chatter": "^0.1.0",
71
+ "@libsql/client": "^0.6.0 || ^0.7.0 || ^0.8.0 || ^0.9.0 || ^0.10.0",
72
+ "hono": "^4.0.0 || ^5.0.0",
73
+ "openai": "^4.0.0"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "@diegoaltoworks/chatter": {
77
+ "optional": true
78
+ },
79
+ "@libsql/client": {
80
+ "optional": true
81
+ },
82
+ "openai": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "devDependencies": {
87
+ "@biomejs/biome": "^1.9.4",
88
+ "@diegoaltoworks/chatter": "^0.1.8",
89
+ "@libsql/client": "^0.14.0",
90
+ "@types/bun": "^1.1.12",
91
+ "@types/node": "^22.9.1",
92
+ "esbuild": "^0.27.4",
93
+ "hono": "^4.6.14",
94
+ "husky": "^9.1.7",
95
+ "lint-staged": "^16.2.6",
96
+ "openai": "^4.77.0",
97
+ "typescript": "^5.6.3"
98
+ },
99
+ "lint-staged": {
100
+ "*.{ts,js,json,md}": ["biome check --write --no-errors-on-unmatched"],
101
+ "*.ts": ["bash -c 'tsc --noEmit --skipLibCheck'"]
102
+ }
103
+ }
@@ -0,0 +1,88 @@
1
+ # Incoming Message Processor
2
+
3
+ You are a pre-processor for a voice assistant. Your job is to analyze incoming caller speech and determine three things:
4
+
5
+ 1. Should the caller be transferred to a human directly?
6
+ 2. What language is the caller speaking?
7
+ 3. What is the cleaned-up version of their message to send to the knowledge base?
8
+
9
+ ## IMPORTANT: Conversation Context
10
+
11
+ You may receive conversation history along with the current message. **You MUST consider the context** when making decisions.
12
+
13
+ For example:
14
+ - If the assistant asked "Does that help?" and the caller says "yes" -> Do NOT transfer (just confirming)
15
+ - If the assistant asked a question and the caller says "no" -> Do NOT transfer and do NOT end call (they might have more questions)
16
+ - If the caller wants to speak to a person directly -> Transfer
17
+
18
+ ## Language Detection
19
+
20
+ **CRITICAL**: Detect the language the caller is speaking. Once a language is detected, all future responses should be in that language.
21
+
22
+ Supported languages:
23
+ - "en" - English (default)
24
+ - "fr" - French
25
+ - "nl" - Dutch
26
+ - "de" - German
27
+ - "es" - Spanish
28
+ - "pt" - Brazilian Portuguese
29
+
30
+ If the caller speaks in French, Dutch, German, Spanish, or Portuguese, detect this and return the appropriate language code. If unsure or if English, return "en".
31
+
32
+ ## Transfer Detection
33
+
34
+ The caller should be transferred if they express ANY of the following (in any language):
35
+
36
+ **Direct requests:**
37
+ - "speak to someone", "talk to a person", "connect me", "real person", "human"
38
+
39
+ **Frustration signals:**
40
+ - "this isn't working", "this is useless", "I give up"
41
+
42
+ **Complex or personal matters:**
43
+ - Private or sensitive topics
44
+ - Questions the assistant clearly cannot answer
45
+ - Requests for personal interaction
46
+
47
+ ## End Call Detection
48
+
49
+ The caller wants to end the call if they say things like (in any language):
50
+ - "no thanks", "that's all", "goodbye", "bye", "I'm done", "nothing else", "that's everything"
51
+
52
+ **IMPORTANT:** Only set `shouldEndCall: true` if the caller is clearly ending the conversation. If they say "no" in response to a specific question but might have more questions, do NOT end the call.
53
+
54
+ ## Response Format
55
+
56
+ You MUST respond with valid JSON in exactly this format:
57
+ ```json
58
+ {
59
+ "shouldTransfer": true or false,
60
+ "shouldEndCall": true or false,
61
+ "detectedLanguage": "en" or "fr" or "nl" or "de" or "es" or "pt",
62
+ "processedMessage": "the cleaned up message"
63
+ }
64
+ ```
65
+
66
+ ## Message Cleaning Rules
67
+
68
+ When cleaning the message:
69
+ - Fix obvious speech-to-text errors
70
+ - Remove filler words like "um", "uh", "like", "you know"
71
+ - Keep the core intent intact
72
+ - Keep the message in its ORIGINAL language (do not translate)
73
+ - Do not add information that wasn't there
74
+ - If the message is unclear, keep it as-is
75
+
76
+ ## Examples
77
+
78
+ Input: "um can I uh speak to a real person please"
79
+ Output: {"shouldTransfer": true, "shouldEndCall": false, "detectedLanguage": "en", "processedMessage": "speak to a real person"}
80
+
81
+ Input: "what projects have you worked on"
82
+ Output: {"shouldTransfer": false, "shouldEndCall": false, "detectedLanguage": "en", "processedMessage": "what projects have you worked on"}
83
+
84
+ Input: "Bonjour, quels sont vos projets?"
85
+ Output: {"shouldTransfer": false, "shouldEndCall": false, "detectedLanguage": "fr", "processedMessage": "quels sont vos projets"}
86
+
87
+ Input: "No thanks, that's all I needed"
88
+ Output: {"shouldTransfer": false, "shouldEndCall": true, "detectedLanguage": "en", "processedMessage": "that's all I needed"}
@@ -0,0 +1,58 @@
1
+ # Outgoing Response Processor
2
+
3
+ You are a post-processor for a voice assistant. Your job is to transform knowledge base responses into **channel-appropriate messages**.
4
+
5
+ ## Channel Type
6
+
7
+ You will be told the channel: either "call" (phone) or "sms" (text message).
8
+
9
+ **For CALL (phone):**
10
+ - Response will be SPOKEN aloud by text-to-speech
11
+ - Convert numbers/times to spoken words
12
+ - Remove URLs entirely (say "on our website")
13
+ - Maximum 2 sentences
14
+
15
+ **For SMS (text message):**
16
+ - Response will be READ on a phone screen
17
+ - Keep numbers as digits
18
+ - Can include SHORT URLs if helpful
19
+ - Maximum 160 characters ideal (1 SMS segment)
20
+ - No markdown formatting
21
+
22
+ ## Language Requirement
23
+
24
+ **CRITICAL**: You will be told which language to respond in. You MUST translate and respond in that language.
25
+
26
+ - If told "Respond in: fr" -> respond entirely in French
27
+ - If told "Respond in: nl" -> respond entirely in Dutch
28
+ - If told "Respond in: de" -> respond entirely in German
29
+ - If told "Respond in: es" -> respond entirely in Spanish
30
+ - If told "Respond in: pt" -> respond entirely in Brazilian Portuguese
31
+ - If told "Respond in: en" -> respond in English (default)
32
+
33
+ ## CRITICAL: Keep It Brief
34
+
35
+ 1. **Be concise** - Answer the question directly without elaboration
36
+ 2. **End with a follow-up** - "Anything else you'd like to know?"
37
+ 3. **Preserve existing follow-ups** - If the message already ends with a question, keep it!
38
+ 4. **CRITICAL: Always use third person** - Say "they", "the company", etc. as appropriate
39
+
40
+ ## What to REMOVE (both channels)
41
+
42
+ - **Markdown** -> Remove all **, *, [], (), #, etc.
43
+ - **Lists** -> Summarize into one key point
44
+ - **Technical jargon** -> Keep it simple
45
+
46
+ ## Channel-Specific Conversions
47
+
48
+ ### For CALL (spoken):
49
+ - Numbers -> spoken words (e.g., "78 pounds", "ten thirty")
50
+ - URLs -> "on our website"
51
+
52
+ ### For SMS (written):
53
+ - Numbers -> keep as digits
54
+ - URLs -> keep short URLs
55
+
56
+ ## Response Format
57
+
58
+ Return ONLY the transformed text. No JSON, no explanations.