@fatagnus/convex-feedback 0.2.0 → 0.2.2
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.
package/package.json
CHANGED
|
@@ -642,14 +642,30 @@ export const startBugInterview = action({
|
|
|
642
642
|
});
|
|
643
643
|
|
|
644
644
|
// Start the interview
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
645
|
+
let result;
|
|
646
|
+
try {
|
|
647
|
+
result = await dynamicAgent.generateText(
|
|
648
|
+
ctx,
|
|
649
|
+
{
|
|
650
|
+
threadId,
|
|
651
|
+
customCtx: { sessionId },
|
|
652
|
+
},
|
|
653
|
+
{ prompt: "Start the bug report interview. Greet the user briefly and ask what bug or issue they encountered." }
|
|
654
|
+
);
|
|
655
|
+
} catch (error) {
|
|
656
|
+
// Provide more descriptive error messages based on the error type
|
|
657
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
658
|
+
if (errorMessage.includes("401") || errorMessage.includes("unauthorized")) {
|
|
659
|
+
throw new Error("AI service authentication failed. Please check your OPENROUTER_API_KEY.");
|
|
660
|
+
} else if (errorMessage.includes("429") || errorMessage.includes("rate limit")) {
|
|
661
|
+
throw new Error("AI service rate limited. Please try again in a few moments.");
|
|
662
|
+
} else if (errorMessage.includes("503") || errorMessage.includes("unavailable")) {
|
|
663
|
+
throw new Error("AI service temporarily unavailable. Please try again later.");
|
|
664
|
+
} else if (errorMessage.includes("timeout") || errorMessage.includes("ETIMEDOUT")) {
|
|
665
|
+
throw new Error("AI service request timed out. Please try again.");
|
|
666
|
+
}
|
|
667
|
+
throw new Error(`Failed to start interview: ${errorMessage}`);
|
|
668
|
+
}
|
|
653
669
|
|
|
654
670
|
// Check for pending input request
|
|
655
671
|
const pendingRequest = await ctx.runQuery(
|
|
@@ -758,14 +774,30 @@ export const startFeedbackInterview = action({
|
|
|
758
774
|
});
|
|
759
775
|
|
|
760
776
|
// Start the interview
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
777
|
+
let result;
|
|
778
|
+
try {
|
|
779
|
+
result = await dynamicAgent.generateText(
|
|
780
|
+
ctx,
|
|
781
|
+
{
|
|
782
|
+
threadId,
|
|
783
|
+
customCtx: { sessionId },
|
|
784
|
+
},
|
|
785
|
+
{ prompt: "Start the feedback interview. Greet the user briefly and ask about their idea or suggestion." }
|
|
786
|
+
);
|
|
787
|
+
} catch (error) {
|
|
788
|
+
// Provide more descriptive error messages based on the error type
|
|
789
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
790
|
+
if (errorMessage.includes("401") || errorMessage.includes("unauthorized")) {
|
|
791
|
+
throw new Error("AI service authentication failed. Please check your OPENROUTER_API_KEY.");
|
|
792
|
+
} else if (errorMessage.includes("429") || errorMessage.includes("rate limit")) {
|
|
793
|
+
throw new Error("AI service rate limited. Please try again in a few moments.");
|
|
794
|
+
} else if (errorMessage.includes("503") || errorMessage.includes("unavailable")) {
|
|
795
|
+
throw new Error("AI service temporarily unavailable. Please try again later.");
|
|
796
|
+
} else if (errorMessage.includes("timeout") || errorMessage.includes("ETIMEDOUT")) {
|
|
797
|
+
throw new Error("AI service request timed out. Please try again.");
|
|
798
|
+
}
|
|
799
|
+
throw new Error(`Failed to start interview: ${errorMessage}`);
|
|
800
|
+
}
|
|
769
801
|
|
|
770
802
|
// Check for pending input request
|
|
771
803
|
const pendingRequest = await ctx.runQuery(
|
|
@@ -887,18 +919,34 @@ export const continueInterview = action({
|
|
|
887
919
|
});
|
|
888
920
|
|
|
889
921
|
// Continue the agent
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
922
|
+
let result;
|
|
923
|
+
try {
|
|
924
|
+
result = await dynamicAgent.generateText(
|
|
925
|
+
ctx,
|
|
926
|
+
{
|
|
927
|
+
threadId: args.threadId,
|
|
928
|
+
customCtx: { sessionId: args.sessionId },
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
prompt: `The user responded: ${args.response}
|
|
898
932
|
|
|
899
933
|
Please continue the interview based on their response.`,
|
|
934
|
+
}
|
|
935
|
+
);
|
|
936
|
+
} catch (error) {
|
|
937
|
+
// Provide more descriptive error messages based on the error type
|
|
938
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
939
|
+
if (errorMessage.includes("401") || errorMessage.includes("unauthorized")) {
|
|
940
|
+
throw new Error("AI service authentication failed. Please check your OPENROUTER_API_KEY.");
|
|
941
|
+
} else if (errorMessage.includes("429") || errorMessage.includes("rate limit")) {
|
|
942
|
+
throw new Error("AI service rate limited. Please try again in a few moments.");
|
|
943
|
+
} else if (errorMessage.includes("503") || errorMessage.includes("unavailable")) {
|
|
944
|
+
throw new Error("AI service temporarily unavailable. Please try again later.");
|
|
945
|
+
} else if (errorMessage.includes("timeout") || errorMessage.includes("ETIMEDOUT")) {
|
|
946
|
+
throw new Error("AI service request timed out. Please try again.");
|
|
900
947
|
}
|
|
901
|
-
|
|
948
|
+
throw new Error(`Failed to continue interview: ${errorMessage}`);
|
|
949
|
+
}
|
|
902
950
|
|
|
903
951
|
// Check if interview is complete (session has generated report)
|
|
904
952
|
const session = await ctx.runQuery(api.agents.feedbackInterviewAgent.getSessionByThread, {
|
package/src/convex/index.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
export * as bugReports from './bugReports';
|
|
9
9
|
export * as feedback from './feedback';
|
|
10
10
|
export * as supportTeams from './supportTeams';
|
|
11
|
+
export * as inputRequests from './inputRequests';
|
|
12
|
+
export * as agents from './agents';
|
|
11
13
|
|
|
12
14
|
// Re-export schema types and validators
|
|
13
15
|
export {
|
|
@@ -752,11 +752,12 @@ export function BugReportButton({
|
|
|
752
752
|
};
|
|
753
753
|
|
|
754
754
|
// Auto-start interview when interview mode is selected and no interview is active
|
|
755
|
+
// Important: Check for error state to prevent infinite retry loop on failure
|
|
755
756
|
useEffect(() => {
|
|
756
|
-
if (opened && inputMode === 'interview' && enableInterview && !interviewState.threadId && !interviewState.isThinking) {
|
|
757
|
+
if (opened && inputMode === 'interview' && enableInterview && !interviewState.threadId && !interviewState.isThinking && !interviewState.error) {
|
|
757
758
|
handleStartInterview();
|
|
758
759
|
}
|
|
759
|
-
}, [opened, inputMode, enableInterview, interviewState.threadId, interviewState.isThinking, handleStartInterview]);
|
|
760
|
+
}, [opened, inputMode, enableInterview, interviewState.threadId, interviewState.isThinking, interviewState.error, handleStartInterview]);
|
|
760
761
|
|
|
761
762
|
return (
|
|
762
763
|
<>
|
|
@@ -844,9 +845,21 @@ export function BugReportButton({
|
|
|
844
845
|
{interviewState.error && (
|
|
845
846
|
<Alert icon={<IconAlertCircle size={16} />} color="red" title="Interview Error">
|
|
846
847
|
{interviewState.error}
|
|
847
|
-
<
|
|
848
|
-
|
|
849
|
-
|
|
848
|
+
<Group gap="xs" mt="xs">
|
|
849
|
+
<Button
|
|
850
|
+
variant="subtle"
|
|
851
|
+
size="xs"
|
|
852
|
+
onClick={() => {
|
|
853
|
+
// Clear error and retry
|
|
854
|
+
setInterviewState(prev => ({ ...prev, error: null }));
|
|
855
|
+
}}
|
|
856
|
+
>
|
|
857
|
+
Try Again
|
|
858
|
+
</Button>
|
|
859
|
+
<Button variant="subtle" size="xs" onClick={() => setInputMode('form')}>
|
|
860
|
+
Switch to Form
|
|
861
|
+
</Button>
|
|
862
|
+
</Group>
|
|
850
863
|
</Alert>
|
|
851
864
|
)}
|
|
852
865
|
|