-
Notifications
You must be signed in to change notification settings - Fork 113
Classify candidate rejection feedback with Bragi #3563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
🍹 The Update (preview) for dailydotdev/api/prod (at 126d987) was successful. Resource Changes Name Type Operation
~ vpc-native-private-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-expire-super-agent-trial-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-source-public-threshold-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-trending-cron kubernetes:batch/v1:CronJob update
- vpc-native-api-db-migration-e1dc464f kubernetes:batch/v1:Job delete
~ vpc-native-clean-zombie-users-cron kubernetes:batch/v1:CronJob update
~ vpc-native-daily-digest-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-current-streak-cron kubernetes:batch/v1:CronJob update
~ vpc-native-sync-subscription-with-cio-cron kubernetes:batch/v1:CronJob update
~ vpc-native-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-clean-zombie-opportunities-cron kubernetes:batch/v1:CronJob update
~ vpc-native-post-analytics-clickhouse-cron kubernetes:batch/v1:CronJob update
~ vpc-native-ws-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-temporal-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-personalized-digest-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-validate-active-users-cron kubernetes:batch/v1:CronJob update
- vpc-native-api-clickhouse-migration-e1dc464f kubernetes:batch/v1:Job delete
~ vpc-native-update-views-cron kubernetes:batch/v1:CronJob update
~ vpc-native-user-profile-analytics-history-clickhouse-cron kubernetes:batch/v1:CronJob update
~ vpc-native-bg-deployment kubernetes:apps/v1:Deployment update
~ vpc-native-user-profile-updated-sync-cron kubernetes:batch/v1:CronJob update
~ vpc-native-clean-zombie-user-companies-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-source-tag-view-cron kubernetes:batch/v1:CronJob update
+ vpc-native-api-clickhouse-migration-e57b8b25 kubernetes:batch/v1:Job create
~ vpc-native-user-profile-analytics-clickhouse-cron kubernetes:batch/v1:CronJob update
~ vpc-native-generate-search-invites-cron kubernetes:batch/v1:CronJob update
~ vpc-native-check-analytics-report-cron kubernetes:batch/v1:CronJob update
~ vpc-native-clean-zombie-images-cron kubernetes:batch/v1:CronJob update
~ vpc-native-hourly-notification-cron kubernetes:batch/v1:CronJob update
+ vpc-native-api-db-migration-e57b8b25 kubernetes:batch/v1:Job create
~ vpc-native-update-tags-str-cron kubernetes:batch/v1:CronJob update
~ vpc-native-clean-stale-user-transactions-cron kubernetes:batch/v1:CronJob update
~ vpc-native-calculate-top-readers-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-highlighted-views-cron kubernetes:batch/v1:CronJob update
~ vpc-native-personalized-digest-cron kubernetes:batch/v1:CronJob update
~ vpc-native-post-analytics-history-day-clickhouse-cron kubernetes:batch/v1:CronJob update
~ vpc-native-generic-referral-reminder-cron kubernetes:batch/v1:CronJob update
~ vpc-native-update-tag-recommendations-cron kubernetes:batch/v1:CronJob update
~ vpc-native-user-posts-analytics-refresh-cron kubernetes:batch/v1:CronJob update
~ vpc-native-clean-gifted-plus-cron kubernetes:batch/v1:CronJob update
... and 1 other changes |
ce4fe86 to
b0e932a
Compare
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| await queryRunner.query( | ||
| `ALTER TABLE "opportunity_match" | ||
| ADD "rejectionClassification" jsonb DEFAULT null`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also modify here then
| value?: unknown; | ||
| }; | ||
|
|
||
| const mapPreferenceFields = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this?
| ? `${opportunity.title}\n${opportunity.tldr}` | ||
| : undefined; | ||
|
|
||
| const result = await bragiClient.garmr.execute(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This flow is a bit weird, you should probably do this where we request the feedback? This only happens once we get feedback so it won't even trigger for rejection I don't think.
| if (err instanceof ConnectError) { | ||
| logger.error( | ||
| { err, opportunityId, userId, answer: item.answer }, | ||
| 'ConnectError when parsing feedback', | ||
| ); | ||
| return item; | ||
| } | ||
| throw err; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you are using Promise.all, throw on any of them will cancel result for all of them, so I think its better to not throw and ignore errors from bragi, there are retries already.
| public async up(queryRunner: QueryRunner): Promise<void> { | ||
| await queryRunner.query( | ||
| `ALTER TABLE "opportunity_match" | ||
| ADD "rejectionClassification" jsonb`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add column if not exists, also for drop
| }); | ||
|
|
||
| if (!match) { | ||
| logger.warn({ opportunityId, userId }, 'No match found for feedback'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can make all of this warns debug (here and below), no point in spamming logs, agent should know this already 😫
| // Skip rejection classification if already set (idempotent) | ||
| if (match.rejectionClassification) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With #3540 there can be multiple feedbacks, so potentially we need to overwrite it and then save current result in history column
bdb75a7 to
384f737
Compare
Co-authored-by: Ole-Martin Bratteng <[email protected]>
- Don't throw errors in Promise.all to avoid cancelling sibling results - Change warn/error logs to debug to reduce log noise - Allow overwriting rejectionClassification for rematch support - Remove ConnectError-specific handling in favor of catching all errors Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
e07d9f9 to
126d987
Compare
This adds Bragi rejection classification to the opportunity feedback worker while keeping existing per-item feedback parsing. It stores structured rejection reasons and summary on OpportunityMatch via a new JSONB column and migration. The Bragi schema dependency is bumped to 0.2.70 to use the typed classifyRejectionFeedback RPC. Tests now cover storing rejection classification, idempotent skip when already present, and graceful handling of ConnectError.