refactor(insights): share workbook export and ai defaults
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import { DEFAULT_OPENAI_MODEL } from "@capakraken/shared";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import type {
|
||||
ChatCompletion,
|
||||
ChatCompletionCreateParamsNonStreaming,
|
||||
} from "openai/resources/chat/completions/completions";
|
||||
import { z } from "zod";
|
||||
import { createAiClient, isAiConfigured, loggedAiCall, parseAiError } from "../ai-client.js";
|
||||
import type { TRPCContext } from "../trpc.js";
|
||||
@@ -73,13 +78,15 @@ export async function generateProjectNarrative(
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "Project not found" });
|
||||
}
|
||||
|
||||
if (!isAiConfigured(settings)) {
|
||||
if (!settings || !isAiConfigured(settings)) {
|
||||
throw new TRPCError({
|
||||
code: "PRECONDITION_FAILED",
|
||||
message: "AI is not configured. Please set credentials in Admin → Settings.",
|
||||
});
|
||||
}
|
||||
|
||||
const configuredSettings = settings;
|
||||
|
||||
const now = new Date();
|
||||
const totalDays = countBusinessDays(project.startDate, project.endDate);
|
||||
const elapsedDays = countBusinessDays(
|
||||
@@ -125,27 +132,30 @@ export async function generateProjectNarrative(
|
||||
|
||||
${dataContext}`;
|
||||
|
||||
const client = createAiClient(settings);
|
||||
const model = settings.azureOpenAiDeployment;
|
||||
const maxTokens = settings.aiMaxCompletionTokens ?? 300;
|
||||
const temperature = settings.aiTemperature ?? 1;
|
||||
const provider = settings.aiProvider ?? "openai";
|
||||
const client = createAiClient(configuredSettings);
|
||||
const model = configuredSettings.azureOpenAiDeployment ?? DEFAULT_OPENAI_MODEL;
|
||||
const maxTokens = configuredSettings.aiMaxCompletionTokens ?? 300;
|
||||
const temperature = configuredSettings.aiTemperature ?? 1;
|
||||
const provider = configuredSettings.aiProvider ?? "openai";
|
||||
|
||||
let narrative = "";
|
||||
try {
|
||||
const completion = await loggedAiCall(provider, model, prompt.length, () =>
|
||||
client.chat.completions.create({
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You are a project management analyst providing brief executive summaries. Be factual and action-oriented.",
|
||||
},
|
||||
{ role: "user", content: prompt },
|
||||
],
|
||||
max_completion_tokens: maxTokens,
|
||||
model,
|
||||
...(temperature !== 1 ? { temperature } : {}),
|
||||
}),
|
||||
const completionRequest: ChatCompletionCreateParamsNonStreaming = {
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You are a project management analyst providing brief executive summaries. Be factual and action-oriented.",
|
||||
},
|
||||
{ role: "user", content: prompt },
|
||||
],
|
||||
max_completion_tokens: maxTokens,
|
||||
model,
|
||||
stream: false,
|
||||
...(temperature !== 1 ? { temperature } : {}),
|
||||
};
|
||||
|
||||
const completion = await loggedAiCall<ChatCompletion>(provider, model, prompt.length, () =>
|
||||
client.chat.completions.create(completionRequest),
|
||||
);
|
||||
narrative = completion.choices[0]?.message?.content?.trim() ?? "";
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user