Abid Ali Awan commited on
Commit
679be47
·
1 Parent(s): f6fe0ea

Remove education level from research profile

Browse files
README.md CHANGED
@@ -15,11 +15,11 @@ short_description: Find funds with AI.
15
 
16
  **Find funds with AI.**
17
 
18
- ScholarScope is an AI-powered grant and scholarship research agent. Users provide six profile fields—origin, what they are applying for, field of study, funding type, current education level, and preferences—then receive ranked opportunities with eligibility analysis and direct source links.
19
 
20
  ## How It Works
21
 
22
- 1. Validate and normalize the six profile fields.
23
  2. Build three short, complementary searches from the profile.
24
  3. Run those searches concurrently without scraping every result.
25
  4. Remove duplicate, social-media, and known aggregator links, then cheaply rank the remaining URLs.
 
15
 
16
  **Find funds with AI.**
17
 
18
+ ScholarScope is an AI-powered grant and scholarship research agent. Users provide five profile fields—origin, what they are applying for, field of study, funding type, and preferences—then receive ranked opportunities with eligibility analysis and direct source links.
19
 
20
  ## How It Works
21
 
22
+ 1. Validate and normalize the five profile fields.
23
  2. Build three short, complementary searches from the profile.
24
  3. Run those searches concurrently without scraping every result.
25
  4. Remove duplicate, social-media, and known aggregator links, then cheaply rank the remaining URLs.
output/jupyter-notebook/scholarscope-beginner-guide.ipynb CHANGED
@@ -130,7 +130,6 @@
130
  " 'applying_for': \"Master's degree\",\n",
131
  " 'field_of_study': 'Computer science or data science',\n",
132
  " 'funding_type': 'Scholarship',\n",
133
- " 'education_level': \"Bachelor's degree completed\",\n",
134
  " 'preferences': 'Fully funded and open to international applicants'}"
135
  ]
136
  },
@@ -145,7 +144,6 @@
145
  " \"applying_for\": \"Master's degree\",\n",
146
  " \"field_of_study\": \"Computer science or data science\",\n",
147
  " \"funding_type\": \"Scholarship\",\n",
148
- " \"education_level\": \"Bachelor's degree completed\",\n",
149
  " \"preferences\": \"Fully funded and open to international applicants\",\n",
150
  "}\n",
151
  "\n",
@@ -188,7 +186,7 @@
188
  "\n",
189
  "required_fields = (\n",
190
  " \"origin\", \"applying_for\", \"field_of_study\",\n",
191
- " \"funding_type\", \"education_level\", \"preferences\",\n",
192
  ")\n",
193
  "missing_fields = [name for name in required_fields if not profile.get(name)]\n",
194
  "\n",
@@ -238,7 +236,7 @@
238
  ")\n",
239
  "\n",
240
  "queries = [\n",
241
- " f'current official {base} with {profile[\"education_level\"]} application deadline',\n",
242
  " f'direct provider {base} {profile[\"preferences\"]} eligibility funding',\n",
243
  " f'university government foundation {profile[\"funding_type\"]} '\n",
244
  " f'{profile[\"applying_for\"]} {profile[\"field_of_study\"]} '\n",
 
130
  " 'applying_for': \"Master's degree\",\n",
131
  " 'field_of_study': 'Computer science or data science',\n",
132
  " 'funding_type': 'Scholarship',\n",
 
133
  " 'preferences': 'Fully funded and open to international applicants'}"
134
  ]
135
  },
 
144
  " \"applying_for\": \"Master's degree\",\n",
145
  " \"field_of_study\": \"Computer science or data science\",\n",
146
  " \"funding_type\": \"Scholarship\",\n",
 
147
  " \"preferences\": \"Fully funded and open to international applicants\",\n",
148
  "}\n",
149
  "\n",
 
186
  "\n",
187
  "required_fields = (\n",
188
  " \"origin\", \"applying_for\", \"field_of_study\",\n",
189
+ " \"funding_type\", \"preferences\",\n",
190
  ")\n",
191
  "missing_fields = [name for name in required_fields if not profile.get(name)]\n",
192
  "\n",
 
236
  ")\n",
237
  "\n",
238
  "queries = [\n",
239
+ " f'current official {base} application deadline',\n",
240
  " f'direct provider {base} {profile[\"preferences\"]} eligibility funding',\n",
241
  " f'university government foundation {profile[\"funding_type\"]} '\n",
242
  " f'{profile[\"applying_for\"]} {profile[\"field_of_study\"]} '\n",
src/olostep_client.py CHANGED
@@ -189,10 +189,9 @@ def _build_queries(profile: UserProfile) -> list[str]:
189
  f"{profile.funding_type} for students from {profile.origin} "
190
  f"applying for {profile.applying_for} in {profile.field_of_study}"
191
  )
192
- education = f"with {profile.education_level}"
193
  preferences = profile.preferences or "international applicants"
194
  return [
195
- f"current official {base} {education} application deadline",
196
  f"direct provider {base} {preferences} eligibility funding",
197
  f"university government foundation {profile.funding_type} "
198
  f"{profile.applying_for} {profile.field_of_study} {profile.origin} {preferences}",
 
189
  f"{profile.funding_type} for students from {profile.origin} "
190
  f"applying for {profile.applying_for} in {profile.field_of_study}"
191
  )
 
192
  preferences = profile.preferences or "international applicants"
193
  return [
194
+ f"current official {base} application deadline",
195
  f"direct provider {base} {preferences} eligibility funding",
196
  f"university government foundation {profile.funding_type} "
197
  f"{profile.applying_for} {profile.field_of_study} {profile.origin} {preferences}",
src/schemas.py CHANGED
@@ -12,7 +12,6 @@ class UserProfile(BaseModel):
12
  applying_for: str = Field(min_length=2, max_length=120)
13
  field_of_study: str = Field(min_length=2, max_length=180)
14
  funding_type: str = Field(min_length=2, max_length=120)
15
- education_level: str = Field(min_length=2, max_length=120)
16
  preferences: str = Field(default="", max_length=800)
17
 
18
  @field_validator("*", mode="before")
@@ -28,7 +27,6 @@ class UserProfile(BaseModel):
28
  self.applying_for,
29
  self.field_of_study,
30
  self.funding_type,
31
- self.education_level,
32
  self.preferences,
33
  ]
34
  return " ".join(part for part in parts if part)
 
12
  applying_for: str = Field(min_length=2, max_length=120)
13
  field_of_study: str = Field(min_length=2, max_length=180)
14
  funding_type: str = Field(min_length=2, max_length=120)
 
15
  preferences: str = Field(default="", max_length=800)
16
 
17
  @field_validator("*", mode="before")
 
27
  self.applying_for,
28
  self.field_of_study,
29
  self.funding_type,
 
30
  self.preferences,
31
  ]
32
  return " ".join(part for part in parts if part)
src/ui.py CHANGED
@@ -21,7 +21,6 @@ class ResearchRequest(BaseModel):
21
  applying_for: str
22
  field_of_study: str
23
  funding_type: str
24
- education_level: str
25
  preferences: str = ""
26
 
27
 
@@ -791,16 +790,6 @@ FRONTEND_HTML = r"""
791
  </select>
792
  </label>
793
  <label class="field full"><span>Field of study</span><input name="field_of_study" value="Computer science or data science" required></label>
794
- <label class="field"><span>Current education level</span>
795
- <select name="education_level">
796
- <option>High school</option>
797
- <option selected>Bachelor's degree completed</option>
798
- <option>Master's degree completed</option>
799
- <option>PhD</option>
800
- <option>Postdoctoral</option>
801
- <option>Professional</option>
802
- </select>
803
- </label>
804
  <fieldset class="field">
805
  <span>Funding type &mdash; pick any</span>
806
  <div class="checkgroup">
@@ -896,9 +885,9 @@ FRONTEND_HTML = r"""
896
  let apiReady = null;
897
 
898
  const EXAMPLE_PROFILES = {
899
- "ai-pakistan": { origin: "Pakistan", applying_for: "Master's degree", field_of_study: "Artificial intelligence", funding_type: "Scholarship", education_level: "Bachelor's degree completed", preferences: "Fully funded, responsible AI, international applicants" },
900
- "health-africa": { origin: "Kenya", applying_for: "Postdoctoral research", field_of_study: "Public health", funding_type: "Research grant", education_level: "PhD", preferences: "African institutions and implementation research" },
901
- "cs-canada": { origin: "Canada", applying_for: "PhD", field_of_study: "Computer science", funding_type: "Fellowship", education_level: "Master's degree completed", preferences: "AI safety, systems, and human-centered computing" }
902
  };
903
 
904
  const escapeHtml = (v) => String(v ?? "").replace(/[&<>"']/g, (c) => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
 
21
  applying_for: str
22
  field_of_study: str
23
  funding_type: str
 
24
  preferences: str = ""
25
 
26
 
 
790
  </select>
791
  </label>
792
  <label class="field full"><span>Field of study</span><input name="field_of_study" value="Computer science or data science" required></label>
 
 
 
 
 
 
 
 
 
 
793
  <fieldset class="field">
794
  <span>Funding type &mdash; pick any</span>
795
  <div class="checkgroup">
 
885
  let apiReady = null;
886
 
887
  const EXAMPLE_PROFILES = {
888
+ "ai-pakistan": { origin: "Pakistan", applying_for: "Master's degree", field_of_study: "Artificial intelligence", funding_type: "Scholarship", preferences: "Fully funded, responsible AI, international applicants" },
889
+ "health-africa": { origin: "Kenya", applying_for: "Postdoctoral research", field_of_study: "Public health", funding_type: "Research grant", preferences: "African institutions and implementation research" },
890
+ "cs-canada": { origin: "Canada", applying_for: "PhD", field_of_study: "Computer science", funding_type: "Fellowship", preferences: "AI safety, systems, and human-centered computing" }
891
  };
892
 
893
  const escapeHtml = (v) => String(v ?? "").replace(/[&<>"']/g, (c) => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
tests/test_dataset_store.py CHANGED
@@ -9,7 +9,6 @@ def test_dataset_store_memory_fallback() -> None:
9
  applying_for="Master's degree",
10
  field_of_study="AI",
11
  funding_type="Scholarship",
12
- education_level="Bachelor's degree completed",
13
  preferences="Fully funded",
14
  )
15
  opportunity = Opportunity(title="AI Grant", source_url="https://example.org/grant")
 
9
  applying_for="Master's degree",
10
  field_of_study="AI",
11
  funding_type="Scholarship",
 
12
  preferences="Fully funded",
13
  )
14
  opportunity = Opportunity(title="AI Grant", source_url="https://example.org/grant")
tests/test_live_research_behavior.py CHANGED
@@ -14,7 +14,6 @@ def test_live_mode_returns_empty_state_when_no_pages(monkeypatch) -> None:
14
  applying_for="Master's degree",
15
  field_of_study="Artificial intelligence",
16
  funding_type="Scholarship",
17
- education_level="Bachelor's degree completed",
18
  preferences="Fully funded",
19
  )
20
  )
@@ -34,7 +33,6 @@ def test_missing_live_keys_returns_configuration_error(monkeypatch) -> None:
34
  applying_for="Master's degree",
35
  field_of_study="Artificial intelligence",
36
  funding_type="Scholarship",
37
- education_level="Bachelor's degree completed",
38
  preferences="Fully funded",
39
  )
40
  )
@@ -62,7 +60,6 @@ def test_live_mode_uses_real_source_fallback_when_ranker_fails(monkeypatch) -> N
62
  applying_for="Master's degree",
63
  field_of_study="Artificial intelligence",
64
  funding_type="Scholarship",
65
- education_level="Bachelor's degree completed",
66
  preferences="Fully funded",
67
  )
68
  )
 
14
  applying_for="Master's degree",
15
  field_of_study="Artificial intelligence",
16
  funding_type="Scholarship",
 
17
  preferences="Fully funded",
18
  )
19
  )
 
33
  applying_for="Master's degree",
34
  field_of_study="Artificial intelligence",
35
  funding_type="Scholarship",
 
36
  preferences="Fully funded",
37
  )
38
  )
 
60
  applying_for="Master's degree",
61
  field_of_study="Artificial intelligence",
62
  funding_type="Scholarship",
 
63
  preferences="Fully funded",
64
  )
65
  )
tests/test_olostep_client.py CHANGED
@@ -10,7 +10,6 @@ def make_profile(funding_type: str = "Scholarship") -> UserProfile:
10
  applying_for="Master's degree",
11
  field_of_study="AI",
12
  funding_type=funding_type,
13
- education_level="Bachelor's degree completed",
14
  preferences="Fully funded and open to international applicants",
15
  )
16
 
 
10
  applying_for="Master's degree",
11
  field_of_study="AI",
12
  funding_type=funding_type,
 
13
  preferences="Fully funded and open to international applicants",
14
  )
15
 
tests/test_schemas.py CHANGED
@@ -10,14 +10,13 @@ def make_profile() -> UserProfile:
10
  applying_for="Master's degree",
11
  field_of_study="AI",
12
  funding_type="Scholarship",
13
- education_level="Bachelor's degree completed",
14
  preferences="Fully funded",
15
  )
16
 
17
 
18
  def test_profile_validation_requires_detail() -> None:
19
  with pytest.raises(ValidationError):
20
- UserProfile(origin="P", applying_for="MS", field_of_study="AI", funding_type="Grant", education_level="BS")
21
 
22
 
23
  def test_dataset_record_creation() -> None:
 
10
  applying_for="Master's degree",
11
  field_of_study="AI",
12
  funding_type="Scholarship",
 
13
  preferences="Fully funded",
14
  )
15
 
16
 
17
  def test_profile_validation_requires_detail() -> None:
18
  with pytest.raises(ValidationError):
19
+ UserProfile(origin="P", applying_for="MS", field_of_study="AI", funding_type="Grant")
20
 
21
 
22
  def test_dataset_record_creation() -> None: