fix: email send frequency + ai ordering (#3604)
Maintain Release Merge PR / update-release-pr (push) Canceled after 0s
Notify HeyPuter / notify (push) Canceled after 0s
release-please / release-please (push) Canceled after 0s

This commit is contained in:
Daniel Salazar
2026-08-18 18:13:55 -07:00
committed by GitHub
parent 57b4cbab66
commit 9debdffc5d
6 changed files with 26 additions and 24 deletions
@@ -1209,14 +1209,6 @@ export class ChatCompletionDriver extends PuterDriver {
);
}
const togetherKey = readKey(providers['together-ai']);
if (togetherKey) {
this.#providers['together-ai'] = new TogetherAIProvider(
{ apiKey: togetherKey },
metering,
);
}
// Ollama — auto-discover local instance unless `enabled: false`.
const ollama = providers['ollama'];
if (ollama?.enabled !== false) {
@@ -1228,6 +1220,18 @@ export class ChatCompletionDriver extends PuterDriver {
);
}
const infron = providers['infron'];
const infronKey = readKey(infron);
if (infronKey) {
this.#providers['infron'] = new InfronProvider(
{
apiKey: infronKey,
apiBaseUrl: infron?.apiBaseUrl as string | undefined,
},
metering,
);
}
const openrouter = providers['openrouter'];
const openrouterKey = readKey(openrouter);
if (openrouterKey) {
@@ -1240,14 +1244,10 @@ export class ChatCompletionDriver extends PuterDriver {
);
}
const infron = providers['infron'];
const infronKey = readKey(infron);
if (infronKey) {
this.#providers['infron'] = new InfronProvider(
{
apiKey: infronKey,
apiBaseUrl: infron?.apiBaseUrl as string | undefined,
},
const togetherKey = readKey(providers['together-ai']);
if (togetherKey) {
this.#providers['together-ai'] = new TogetherAIProvider(
{ apiKey: togetherKey },
metering,
);
}
@@ -81,7 +81,7 @@ export class AzureChatProvider implements IChatProvider {
baseURL: config.apiURL,
});
}
checkModeration(_text: string): { flagged: boolean; categories: string[] } {
checkModeration(_text: string) {
throw new Error('Method not implemented.');
}
@@ -180,7 +180,7 @@ export class AzureChatProvider implements IChatProvider {
// })
const userIdentifier =
actor.user?.id + actor.app?.uid ? `:${actor?.app?.uid}` : '';
`${actor.user?.id}` + actor.app?.uid ? `:${actor?.app?.uid}` : '';
// Resolve any `puter_path` content parts into inline base64 data URLs.
// Chat Completions doesn't support file uploads, so this is the only
@@ -146,7 +146,7 @@ export class OpenAiResponsesChatProvider implements IChatProvider {
// })
const userIdentifier =
actor?.user.id + actor?.app?.uid ? `:${actor?.app?.uid}` : '';
`${actor?.user.id}` + actor?.app?.uid ? `:${actor?.app?.uid}` : '';
// Resolve any `puter_path` content parts into inline base64 data URLs
// before the Responses API sees them.
@@ -260,7 +260,7 @@ export class OpenAiResponsesChatProvider implements IChatProvider {
this.#meteringService.utilRecordUsageObject(
trackedUsage,
actor,
actor!,
`openai:${modelUsed?.id}`,
costsOverrideFromModel,
);
+3 -1
View File
@@ -146,5 +146,7 @@ export interface IChatProvider {
list(): string[] | Promise<string[]>;
getDefaultModel(): string;
complete(arg: ICompleteArguments): Promise<IChatCompleteResult>;
checkModeration(text: string): { flagged: boolean; categories: string[] };
checkModeration(
text: string,
): Promise<{ flagged: boolean; categories?: string[] }> | void;
}
@@ -564,7 +564,7 @@ export const handle_completion_output = async (
* @param {(args: {
* usage: import('openai/resources/completions.mjs').CompletionUsage;
* }) => unknown} params.usage_calculator
* @returns
* @returns {ReturnType<import('../types').IChatProvider['complete']>}
*/
export const handle_completion_output_responses_api = async ({
deviations,
@@ -56,11 +56,11 @@ export const SHARE_NOTIFY_RECIPIENT_DAILY_LIMIT = 50;
* span goes as a single message. Email can't be rewritten the way the in-app
* notification can, so it gets the grouped wording by waiting instead.
*/
export const SHARE_EMAIL_BATCH_SECONDS = 90;
export const SHARE_EMAIL_BATCH_SECONDS = 30;
// Long enough to list, claim and send; short enough that a crashed flusher
// doesn't strand the digest.
const DIGEST_LOCK_SECONDS = 30;
const DIGEST_LOCK_SECONDS = 20;
// Ceiling on how long an entry may sit unflushed: a node dying with the only
// timer leaves entries behind, and mail this stale is noise rather than news.