-
Notifications
You must be signed in to change notification settings - Fork 1
paragraph counts. restore unwrapped and other fixes #10
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?
Changes from all commits
2d6c7ea
03d4d5c
096e5cd
1bf9a2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -68,3 +68,5 @@ fastlane/test_output | |
|
|
||
| claude-agent-sdk-demos | ||
| xcuserdata | ||
|
|
||
| apps/pipeline/app.log | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,50 @@ | ||||||||||||||||||||||
| import OpenAI from "openai"; | ||||||||||||||||||||||
| import { type z } from "zod"; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const endpoint = "https://bookgenius.services.ai.azure.com/openai/v1/"; | ||||||||||||||||||||||
| const model = "grok-4-fast-reasoning"; | ||||||||||||||||||||||
| const api_key = process.env.AZURE_GROK_KEY; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const client = new OpenAI({ baseURL: endpoint, apiKey: api_key }); | ||||||||||||||||||||||
|
Comment on lines
+6
to
+8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The const api_key = process.env.AZURE_GROK_KEY;
if (!api_key) {
throw new Error("Missing environment variable: AZURE_GROK_KEY");
}
const client = new OpenAI({ baseURL: endpoint, apiKey: api_key });
Comment on lines
+6
to
+8
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing API key validation before client initialization. If 🛡️ Proposed fix const api_key = process.env.AZURE_GROK_KEY;
+
+if (!api_key) {
+ throw new Error("Missing AZURE_GROK_KEY environment variable");
+}
const client = new OpenAI({ baseURL: endpoint, apiKey: api_key });📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const callGrokAzure = async (prompt: string) => { | ||||||||||||||||||||||
| const completion = await client.chat.completions.create({ | ||||||||||||||||||||||
| messages: [{ role: "user", content: prompt }], | ||||||||||||||||||||||
| model, | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return completion.choices[0].message.content; | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
Comment on lines
+10
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return type may be null; consider handling.
🛡️ Proposed fix to handle null content-export const callGrokAzure = async (prompt: string) => {
+export const callGrokAzure = async (prompt: string): Promise<string> => {
const completion = await client.chat.completions.create({
messages: [{ role: "user", content: prompt }],
model,
});
- return completion.choices[0].message.content;
+ const content = completion.choices[0].message.content;
+ if (content === null) {
+ throw new Error("Model returned null content");
+ }
+ return content;
};🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| export const callGrokAzureWithSchema = async <T>(prompt: string, zodSchema: z.ZodSchema<T>) => { | ||||||||||||||||||||||
| const completion = await client.chat.completions.create({ | ||||||||||||||||||||||
| messages: [{ role: "user", content: prompt }], | ||||||||||||||||||||||
| model, | ||||||||||||||||||||||
| response_format: { | ||||||||||||||||||||||
| type: "json_schema", | ||||||||||||||||||||||
| json_schema: { | ||||||||||||||||||||||
| name: "response", | ||||||||||||||||||||||
| strict: true, | ||||||||||||||||||||||
| // @ts-expect-error(zod typing) | ||||||||||||||||||||||
| schema: zodSchema.shape, | ||||||||||||||||||||||
|
Comment on lines
+28
to
+29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using Consider using a library like import { zodToJsonSchema } from 'zod-to-json-schema';
// ... inside callGrokAzureWithSchema
const jsonSchema = zodToJsonSchema(zodSchema);
const completion = await client.chat.completions.create({
// ...
response_format: {
type: "json_schema",
json_schema: {
name: "response",
strict: true,
schema: jsonSchema,
},
},
});This will require adding |
||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| let result: T; | ||||||||||||||||||||||
| try { | ||||||||||||||||||||||
| result = JSON.parse(completion.choices[0].message.content as string) as T; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API response const content = completion.choices[0].message.content;
if (content === null) {
throw new Error("Received null content from the model.");
}
result = JSON.parse(content) as T; |
||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||
| console.error("Error parsing JSON", e); | ||||||||||||||||||||||
| throw e; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| return result; | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // if (require.main === module) { | ||||||||||||||||||||||
| // const schema = z.object({ name: z.string(), age: z.number() }); | ||||||||||||||||||||||
| // const prompt = "What is my name? My name is John Doe and I'm 30"; | ||||||||||||||||||||||
| // const result = await callGrokAzureWithSchema(prompt, schema); | ||||||||||||||||||||||
| // console.log(result); | ||||||||||||||||||||||
| // console.log(result.name); | ||||||||||||||||||||||
| // console.log(result.age); | ||||||||||||||||||||||
| // } | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,6 @@ export const callO3WithSchema = async <T>( | |
| model: openai(model), | ||
| schema: zodSchema, | ||
| prompt, | ||
| // providerOptions: { google: { thinkingConfig: { thinkingBudget: 0, includeThoughts: true } } }, | ||
| experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true }, | ||
| }); | ||
|
|
||
|
|
@@ -36,7 +35,7 @@ export const callGpt5 = async <T = string>( | |
| ) => { | ||
| const chatCompletion = await client.chat.completions.create({ | ||
| messages: [{ role: "user", content: prompt }], | ||
| model: "gpt-5.1", | ||
| model: "gpt-5.2", | ||
| reasoning_effort: "medium", | ||
|
Comment on lines
36
to
39
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: As of February 5, 2026, GPT‑5.2 is available to all developers in the OpenAI API, including the Chat Completions API.
Citations:
🏁 Script executed: cat -n apps/pipeline/src/callO3.tsRepository: TheBrainFamily/BookgeniusPlayer Length of output: 1671 Remove the review concern: The model is officially supported for all developers as of February 2026, including the direct OpenAI SDK path used here. However, the 🤖 Prompt for AI Agents |
||
| }); | ||
| return chatCompletion.choices[0].message.content as string; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| export function logError(contextMessage: string, err: unknown) { | ||
| if (err instanceof Error) { | ||
| console.error(`${contextMessage} ${err.message}`); | ||
| console.error(err.stack); | ||
| return; | ||
| } | ||
| console.error(`${contextMessage} ${String(err)}`); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { JSDOM } from "jsdom"; | ||
|
|
||
| let initialized = false; | ||
|
|
||
| export function ensureDomParser(): void { | ||
| if (typeof (globalThis as { DOMParser?: unknown }).DOMParser !== "undefined") { | ||
| return; | ||
| } | ||
| if (initialized) { | ||
| return; | ||
| } | ||
|
|
||
| const { window } = new JSDOM(""); | ||
| (globalThis as { DOMParser: typeof window.DOMParser }).DOMParser = window.DOMParser; | ||
| initialized = true; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import { | ||
| countParagraphsFromChapterHtml, | ||
| type ParagraphCountOptions, | ||
| } from "@player/services/htmlNormalizer"; | ||
| import { ensureDomParser } from "./domParser"; | ||
|
|
||
| export function computeParagraphCount(html: string, options?: ParagraphCountOptions): number { | ||
| ensureDomParser(); | ||
| return countParagraphsFromChapterHtml(html, options); | ||
| } |
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.
Missing
thinkingConfigdespite function name implying thinking is enabled.The function
callGeminiWithThinkingno longer configures thinking in providerOptions. Compare withcallFastGemini(lines 20-25) which includesthinkingConfig: { thinkingBudget: 256, includeThoughts: true }. The function name is now misleading—either add the thinking configuration or rename the function.Additionally, this function uses
HarmBlockThreshold.OFFwhile all other functions in this file useHarmBlockThreshold.BLOCK_NONE. This inconsistency may cause unexpected behavior differences between Gemini call variants.Proposed fix to add thinking configuration
const { text } = await generateText({ model: google("gemini-3-flash-preview"), prompt, experimental_telemetry: { isEnabled: true, recordInputs: true, recordOutputs: true }, - providerOptions: { google: { safetySettings } }, + providerOptions: { + google: { + safetySettings, + thinkingConfig: { thinkingBudget: 1024, includeThoughts: true }, + }, + }, });🤖 Prompt for AI Agents