Skip to content

Commit c6b029c

Browse files
committed
Reliability fixes, CI workflow, README, and LICENSE
- 10-round review: null safety, synchronize_session=False, atomicity, evidence chain linking - JSON parser: string-aware bracket matching to handle } inside string values - LLM client: propagate response_format to fallback model calls - Schemas: score normalization, CalibrationResponse cleanup, QualityScoreExtracted dict fallback - Streamlit: .get() guards throughout, type-safe confidence/quality rendering - CI: GitHub Actions workflow for Python 3.11/3.12 - README: JTBD structure with badges - LICENSE: Apache 2.0
1 parent 0671cbc commit c6b029c

34 files changed

Lines changed: 1749 additions & 240 deletions

.github/workflows/ci.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.11", "3.12"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install dependencies
25+
run: pip install -e ".[dev]"
26+
27+
- name: Run tests
28+
run: pytest -v

LICENSE

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
Apache License
2+
Version 2.0, January 2004
3+
http://www.apache.org/licenses/
4+
5+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6+
7+
1. Definitions.
8+
9+
"License" shall mean the terms and conditions for use, reproduction,
10+
and distribution as defined by Sections 1 through 9 of this document.
11+
12+
"Licensor" shall mean the copyright owner or entity authorized by
13+
the copyright owner that is granting the License.
14+
15+
"Legal Entity" shall mean the union of the acting entity and all
16+
other entities that control, are controlled by, or are under common
17+
control with that entity. For the purposes of this definition,
18+
"control" means (i) the power, direct or indirect, to cause the
19+
direction or management of such entity, whether by contract or
20+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
21+
outstanding shares, or (iii) beneficial ownership of such entity.
22+
23+
"You" (or "Your") shall mean an individual or Legal Entity
24+
exercising permissions granted by this License.
25+
26+
"Source" form shall mean the preferred form for making modifications,
27+
including but not limited to software source code, documentation
28+
source, and configuration files.
29+
30+
"Object" form shall mean any form resulting from mechanical
31+
transformation or translation of a Source form, including but
32+
not limited to compiled object code, generated documentation,
33+
and conversions to other media types.
34+
35+
"Work" shall mean the work of authorship made available under
36+
the License, as indicated by a copyright notice that is included in
37+
or attached to the work (an example is provided in the Appendix below).
38+
39+
"Derivative Works" shall mean any work, whether in Source or Object
40+
form, that is based on (or derived from) the Work and for which the
41+
editorial revisions, annotations, elaborations, or other modifications
42+
represent, as a whole, an original work of authorship. For the purposes
43+
of this License, Derivative Works shall not include works that remain
44+
separable from, or merely link (or bind by name) to the interfaces of,
45+
the Work and Derivative Works thereof.
46+
47+
"Contribution" shall mean, as submitted to the Licensor for inclusion
48+
in the Work by the copyright owner or by an individual or Legal Entity
49+
authorized to submit on behalf of the copyright owner. For the purposes
50+
of this definition, "submitted" means any form of electronic, verbal,
51+
or written communication sent to the Licensor or its representatives,
52+
including but not limited to communication on electronic mailing lists,
53+
source code control systems, and issue tracking systems that are managed
54+
by, or on behalf of, the Licensor for the purpose of discussing and
55+
improving the Work, but excluding communication that is conspicuously
56+
marked or designated in writing by the copyright owner as "Not a
57+
Contribution."
58+
59+
"Contributor" shall mean Licensor and any Legal Entity on behalf of
60+
whom a Contribution has been received by the Licensor and included
61+
within the Work.
62+
63+
2. Grant of Copyright License. Subject to the terms and conditions of
64+
this License, each Contributor hereby grants to You a perpetual,
65+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
66+
copyright license to reproduce, prepare Derivative Works of,
67+
publicly display, publicly perform, sublicense, and distribute the
68+
Work and such Derivative Works in Source or Object form.
69+
70+
3. Grant of Patent License. Subject to the terms and conditions of
71+
this License, each Contributor hereby grants to You a perpetual,
72+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
73+
(except as stated in this section) patent license to make, have made,
74+
use, offer to sell, sell, import, and otherwise transfer the Work,
75+
where such license applies only to those patent contributions
76+
Licensable by such Contributor that are necessarily infringed by
77+
their Contribution(s) alone or by the combined work of their
78+
Contribution(s) with the Work to which such Contribution(s) was
79+
submitted. If You institute patent litigation against any entity
80+
(including a cross-claim or counterclaim in a lawsuit) alleging that
81+
the Work or any form of Contribution embodying the Work constitutes
82+
direct or contributory patent infringement, then any patent licenses
83+
granted to You under this License for that Work shall terminate as of
84+
the date such litigation is filed.
85+
86+
4. Redistribution. You may reproduce and distribute copies of the
87+
Work or Derivative Works thereof in any medium, with or without
88+
modifications, and in Source or Object form, provided that You
89+
meet the following conditions:
90+
91+
(a) You must give any other recipients of the Work or Derivative
92+
Works a copy of this License; and
93+
94+
(b) You must cause any modified files to carry prominent notices
95+
stating that You changed the files; and
96+
97+
(c) You must retain, in the Source form of any Derivative Works
98+
that You distribute, all copyright, patent, trademark, and
99+
attribution notices from the Source form of the Work,
100+
excluding those notices that do not pertain to any part of
101+
the Derivative Works; and
102+
103+
(d) If the Work includes a "NOTICE" text file as part of its
104+
distribution, You must include a readable copy of the
105+
attribution notices contained within such NOTICE file, in
106+
at least one of the following places: within a NOTICE text
107+
file distributed as part of the Derivative Works; within
108+
the Source form or documentation, if provided along with the
109+
Derivative Works; or, within a display generated by the
110+
Derivative Works, if and wherever such third-party notices
111+
normally appear. The contents of the NOTICE file are for
112+
informational purposes only and do not modify the License.
113+
You may add Your own attribution notices within Derivative
114+
Works that You distribute, alongside or in addition to the
115+
NOTICE text from the Work, provided that such additional
116+
attribution notices cannot be construed as modifying the
117+
License.
118+
119+
You may add Your own license statement for Your modifications and
120+
may provide additional grant of rights to use, copy, modify, merge,
121+
publish, distribute, sublicense, and/or sell copies of the
122+
Contribution, and to permit persons to whom the Contribution is
123+
furnished to do so.
124+
125+
5. Submission of Contributions. Unless You explicitly state otherwise,
126+
any Contribution intentionally submitted for inclusion in the Work
127+
by You to the Licensor shall be under the terms and conditions of
128+
this License, without any additional terms or conditions.
129+
Notwithstanding the above, nothing herein shall supersede or modify
130+
the terms of any separate license agreement you may have executed
131+
with Licensor regarding such Contributions.
132+
133+
6. Trademarks. This License does not grant permission to use the trade
134+
names, trademarks, service marks, or product names of the Licensor,
135+
except as required for reasonable and customary use in describing the
136+
origin of the Work and reproducing the content of the NOTICE file.
137+
138+
7. Disclaimer of Warranty. Unless required by applicable law or
139+
agreed to in writing, Licensor provides the Work (and each
140+
Contributor provides its Contributions) on an "AS IS" BASIS,
141+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
142+
implied, including, without limitation, any warranties or conditions
143+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
144+
PARTICULAR PURPOSE. You are solely responsible for determining the
145+
appropriateness of using or reproducing the Work and assume any
146+
risks associated with Your exercise of permissions under this License.
147+
148+
8. Limitation of Liability. In no event and under no legal theory,
149+
whether in tort (including negligence), contract, or otherwise,
150+
unless required by applicable law (such as deliberate and grossly
151+
negligent acts) or agreed to in writing, shall any Contributor be
152+
liable to You for damages, including any direct, indirect, special,
153+
incidental, or exemplary damages of any character arising as a
154+
result of this License or out of the use or inability to use the
155+
Work (including but not limited to damages for loss of goodwill,
156+
work stoppage, computer failure or malfunction, or all other
157+
commercial damages or losses), even if such Contributor has been
158+
advised of the possibility of such damages.
159+
160+
9. Accepting Warranty or Additional Liability. While redistributing
161+
the Work or Derivative Works thereof, You may offer, and charge a
162+
fee for, acceptance of support, warranty, indemnity, or other
163+
liability obligations and/or rights consistent with this License.
164+
However, in accepting such obligations, You may offer such conditions
165+
only on Your own behalf and on Your sole responsibility, not on behalf
166+
of any other Contributor, and only if You agree to indemnify, defend,
167+
and hold each Contributor harmless for any liability incurred by, or
168+
claims asserted against, such Contributor by reason of your accepting
169+
any such warranty or additional liability.
170+
171+
END OF TERMS AND CONDITIONS
172+
173+
Copyright 2026 Nissan Pow
174+
175+
Licensed under the Apache License, Version 2.0 (the "License");
176+
you may not use this file except in compliance with the License.
177+
You may obtain a copy of the License at
178+
179+
http://www.apache.org/licenses/LICENSE-2.0
180+
181+
Unless required by applicable law or agreed to in writing, software
182+
distributed under the License is distributed on an "AS IS" BASIS,
183+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184+
See the License for the specific language governing permissions and
185+
limitations under the License.

README.md

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@
22

33
**Elicit what matters from customer interviews. Build the right thing.**
44

5+
[![CI](https://github.com/npow/elicit/actions/workflows/ci.yml/badge.svg)](https://github.com/npow/elicit/actions/workflows/ci.yml)
6+
[![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/)
7+
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
8+
59
You did the interviews. You took the notes. But now you're staring at a pile of Google Docs trying to remember what that one PM said three months ago about dashboards. Sound familiar?
610

711
Elicit reads your interview transcripts and draws out what matters: what jobs your customers are actually trying to do, what's painful, what workarounds they've duct-taped together, and — most importantly — what you should build next, backed by evidence you can trace back to specific quotes.
812

9-
## What you can do
10-
11-
- **Upload interviews** and get structured extractions (jobs-to-be-done, pain points, workarounds) without manually tagging anything
12-
- **See patterns across conversations** — which pains keep coming up, which jobs are universal, where the real opportunities are
13-
- **Get prioritized "build this next" recommendations** with evidence chains that trace back to actual customer quotes
14-
- **Prepare better interviews** with Mom Test guides tailored to your hypothesis
15-
- **Score your interviews** after the fact — find out where you asked leading questions and how to improve
16-
- **Practice with AI customers** before talking to real ones, with real-time feedback when you slip into bad habits
17-
- **Track accuracy** of your synthetic interviews against real ones over time
18-
1913
## Quick start
2014

2115
```bash
@@ -53,7 +47,12 @@ After seeding, open the `Web Interview Examples` project in the UI and run:
5347
5. **Before your next interview**, generate a Mom Test guide. After, score your technique.
5448
6. **Practice first** with synthetic personas that behave like real customers — and call you out when you ask leading questions
5549

56-
Long-running extraction/synthesis/recommendation actions now run through an async job queue. The UI submits jobs and polls status so requests don't have to stay open until completion.
50+
Long-running extraction/synthesis/recommendation actions run through an async job queue. The UI submits jobs and polls status so requests don't have to stay open until completion.
51+
52+
Output quality safeguards:
53+
- LLM score/type normalization (percentages, 0-10 scales, mixed string/number fields)
54+
- Best-effort list parsing for partially malformed model output
55+
- Deterministic fallback synthesis/recommendation generation when LLM parsing returns no usable items
5756

5857
## Async Analysis Jobs (API)
5958

@@ -70,28 +69,6 @@ Each job returns:
7069
- `result`: summary counts for completed jobs
7170
- `error_message`: failure details when status is `failed`
7271

73-
## Demo Interview Sources
74-
75-
The `Web Interview Examples` transcripts are condensed paraphrases for demo/testing (not verbatim copies), grounded in these public interviews:
76-
77-
- [iPhone / smartphone purchase interview](https://jobstobedone.org/radio/iphone-jobs-to-be-done-interview/)
78-
- [Camera purchase interview](https://jobstobedone.org/news/jobs-to-be-done-camera-interview/)
79-
- [Mattress purchase interview](https://jobstobedone.org/radio/the-mattress-interview-part-one/)
80-
81-
## Project structure
82-
83-
```
84-
discovery_engine/
85-
models/ SQLAlchemy data models
86-
schemas/ Pydantic schemas (API + LLM output parsing)
87-
engine/ Core logic (extraction, synthesis, recommendations, coaching, simulation, calibration)
88-
llm/ LLM client + 13 Jinja2 prompt templates
89-
api/ FastAPI routes
90-
streamlit_app/ Streamlit UI (9 pages)
91-
tests/ Tests + sample transcripts
92-
scripts/ Seed data, dev launcher
93-
```
94-
9572
## Configuration
9673

9774
Copy `.env.example` to `.env` and add your keys. Elicit uses three model tiers:
@@ -111,3 +88,25 @@ pip install -e ".[whisper]"
11188
```
11289

11390
Then upload audio files through the API. Requires ~1GB for the base model download.
91+
92+
## Project structure
93+
94+
```
95+
discovery_engine/
96+
models/ SQLAlchemy data models
97+
schemas/ Pydantic schemas (API + LLM output parsing)
98+
engine/ Core logic (extraction, synthesis, recommendations, coaching, simulation, calibration)
99+
llm/ LLM client + 13 Jinja2 prompt templates
100+
api/ FastAPI routes
101+
streamlit_app/ Streamlit UI (9 pages)
102+
tests/ Tests + sample transcripts
103+
scripts/ Seed data, dev launcher
104+
```
105+
106+
## Demo Interview Sources
107+
108+
The `Web Interview Examples` transcripts are condensed paraphrases for demo/testing (not verbatim copies), grounded in these public interviews:
109+
110+
- [iPhone / smartphone purchase interview](https://jobstobedone.org/radio/iphone-jobs-to-be-done-interview/)
111+
- [Camera purchase interview](https://jobstobedone.org/news/jobs-to-be-done-camera-interview/)
112+
- [Mattress purchase interview](https://jobstobedone.org/radio/the-mattress-interview-part-one/)

0 commit comments

Comments
 (0)