Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/agents/lead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export class LeadAgent {
]
.map((m) => `- ${m}`)
.join('\n'),
formOfAddress: formOfAddress(input.language)
formOfAddress: formOfAddress(input.language, input.surveyLanguage)
},
signal
);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/agents/repair_agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { numberResearchQuestions, type Question } from './types.js';
import { extractQuestions } from './question_parser.js';

const SIGNATURE =
'researchQuestions:string "numbered", previousQuestions:json, validationFeedback:string, formOfAddress:string "du or Sie; keep it" -> generatedQuestions:json';
'researchQuestions:string "numbered", previousQuestions:json, validationFeedback:string, formOfAddress:string "du, Sie (German) or you (English); keep it" -> generatedQuestions:json';

/** Built from the registry, so the repair prompt can never drift from what the
* validator accepts. */
Expand Down
13 changes: 9 additions & 4 deletions src/lib/agents/survey_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import generateInstructions from '../../../skills/xlsform/generate-instructions.
// runs "language: informal" still produced "Sie", and "demographics: age"
// made the model write its own age question.
const SIGNATURE =
'researchQuestions:string "numbered; cover every one and tag each question with the numbers it serves", targetGroup?:string, useOfResults?:string, furtherNotes?:string "free-form guidance from the user: things to keep short, terms to avoid, topics to focus on", formOfAddress:string "du or Sie: how every question addresses respondents", surveyLanguage:string "de or en: language of every question, label, hint, title and reasoning", demographicsAddedSeparately?:string "already in the questionnaire; do not ask about these", questionBank?:string "qwac bank questions that matched a keyword search, one per line: id | study | concept | question | answer type" -> title:string "short questionnaire title in the language of the questions", reasoning:string, generatedQuestions:json';
'researchQuestions:string "numbered; cover every one and tag each question with the numbers it serves", targetGroup?:string, useOfResults?:string, furtherNotes?:string "free-form guidance from the user: things to keep short, terms to avoid, topics to focus on", formOfAddress:string "du, Sie (German) or you (English): how every question addresses respondents", surveyLanguage:string "de or en: language of every question, label, hint, title and reasoning", demographicsAddedSeparately?:string "already in the questionnaire; do not ask about these", questionBank?:string "qwac bank questions that matched a keyword search, one per line: id | study | concept | question | answer type" -> title:string "short questionnaire title in the language of the questions", reasoning:string, generatedQuestions:json';

/** "du" or "Sie", as the prompt and the model expect it. */
export function formOfAddress(language: AgentInput['language']): string {
/** "du" or "Sie" for German, "you" for English (no formal/informal split in
* English), as the prompt and the model expect it. */
export function formOfAddress(
language: AgentInput['language'],
surveyLanguage: AgentInput['surveyLanguage'] = 'de'
): string {
if (surveyLanguage === 'en') return 'you';
return language === 'informal' ? 'du' : 'Sie';
}

Expand Down Expand Up @@ -45,7 +50,7 @@ export class SurveyGeneratorAgent {
targetGroup: input.targetGroup,
useOfResults: input.useOfResults,
furtherNotes: input.furtherNotes,
formOfAddress: formOfAddress(input.language),
formOfAddress: formOfAddress(input.language, input.surveyLanguage),
surveyLanguage: input.surveyLanguage,
demographicsAddedSeparately: input.selectedDemographics.join(', ') || undefined,
questionBank: bankHits.length ? renderBankHits(bankHits) : undefined
Expand Down
2 changes: 2 additions & 0 deletions src/lib/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const translations: Record<Locale, Record<string, string>> = {
'wizard.languageLabel': 'Language & Tone',
'wizard.formal': 'Formal (Sie)',
'wizard.informal': 'Informal (Du)',
'wizard.formHintEnglish': 'Form of address only applies to German.',
'wizard.surveyLanguageLabel': 'Survey language',
'wizard.surveyLanguageGerman': 'German',
'wizard.surveyLanguageEnglish': 'English',
Expand Down Expand Up @@ -231,6 +232,7 @@ const translations: Record<Locale, Record<string, string>> = {
'wizard.languageLabel': 'Sprache & Tonalität',
'wizard.formal': 'Förmlich (Sie)',
'wizard.informal': 'Informell (Du)',
'wizard.formHintEnglish': 'Die Anrede gilt nur für deutsche Umfragen.',
'wizard.surveyLanguageLabel': 'Sprache der Umfrage',
'wizard.surveyLanguageGerman': 'Deutsch',
'wizard.surveyLanguageEnglish': 'Englisch',
Expand Down
17 changes: 16 additions & 1 deletion src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,14 @@

<div class="setting-group">
<span class="setting-label">{$t('wizard.languageLabel')}</span>
{#if surveyLanguage === 'en'}
<p class="field-hint">{$t('wizard.formHintEnglish')}</p>
{/if}
<div class="toggle-group">
<button
class="toggle-btn"
class:selected={language === 'formal'}
disabled={surveyLanguage === 'en'}
onclick={() => {
language = 'formal';
}}
Expand All @@ -365,6 +369,7 @@
<button
class="toggle-btn"
class:selected={language === 'informal'}
disabled={surveyLanguage === 'en'}
onclick={() => {
language = 'informal';
}}
Expand Down Expand Up @@ -623,7 +628,17 @@
cursor: pointer;
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
transition: all 0.2s;
/* font-weight is left out: it can't be smoothly interpolated, so
* `transition: all` made it snap while the colour kept fading, and
* the two changes looked out of sync (#43). */
transition:
background-color 0.2s,
border-color 0.2s;
}

.toggle-btn:disabled {
cursor: not-allowed;
opacity: 0.5;
}

.toggle-btn:first-child {
Expand Down
Loading