From e98715f31891f9127b12d50f8b1f79c09cd8ddef Mon Sep 17 00:00:00 2001 From: Igor Silva Date: Wed, 6 Aug 2025 11:18:28 +0100 Subject: [PATCH 1/2] still broken --- convex/action/lifecycle/private.ts | 2 ++ convex/action/private.ts | 37 +++++++++++++++++++------ convex/action/public.ts | 1 + convex/magicRock.tsx | 33 ++++++++++++++++++++++- convex/schedules/lifecycle.ts | 2 ++ convex/schemas/actionSchema.tsx | 2 ++ convex/schemas/skillSchema.tsx | 6 +++++ convex/skills/createAITool.ts | 21 ++++++++++++++- convex/skills/createReactions.ts | 6 ++++- convex/skills/public.ts | 43 +++++++++++++++++++++++++----- convex/tasks/private.ts | 4 +++ convex/users/private.ts | 2 ++ 12 files changed, 142 insertions(+), 17 deletions(-) diff --git a/convex/action/lifecycle/private.ts b/convex/action/lifecycle/private.ts index be55c8da..3e1a0638 100644 --- a/convex/action/lifecycle/private.ts +++ b/convex/action/lifecycle/private.ts @@ -241,6 +241,8 @@ export const _resolve = internalMutation({ skills: result.reactions.map((reaction) => ({ skillKey: reaction.skillKey, args: reaction.args, + status: reaction.status, + result: reaction.result, })), }); } diff --git a/convex/action/private.ts b/convex/action/private.ts index 58a15460..f304d6ef 100644 --- a/convex/action/private.ts +++ b/convex/action/private.ts @@ -22,7 +22,7 @@ export const _add = internalMutation({ owner, depth, shouldReopen, - skills: [{ skillKey, args }], + skills: [{ skillKey, args, status: 'enqueued' }], }); return actionIds[0]; @@ -39,6 +39,8 @@ export const _addMany = internalMutation({ z.object({ skillKey: z.string().describe('The key of the skill to use'), args: z.record(z.any()), + status: z.enum(['enqueued', 'succeeded']), + result: z.string().optional(), }), ), }, @@ -53,22 +55,41 @@ export const _addMany = internalMutation({ // reopen if needed and requested if (!task.isActive && shouldReopen) { - skills.unshift({ skillKey: 'reopen', args: {} }); + skills.unshift({ skillKey: 'reopen', args: {}, status: 'enqueued' }); } const actionIds = await Promise.all( - skills.map((skill) => - ctx.db.insert('actions', { + skills.map((skill) => { + if (skill.status === 'enqueued') { + return ctx.db.insert('actions', { + taskId, + author, + owner, + depth, + status: 'enqueued', + result: null, + skillKey: skill.skillKey, + args: skill.args, + }); + } + + if (!skill.result) throw new Error('Skill result is required for succeeded actions.'); + + return ctx.db.insert('actions', { taskId, author, owner, depth, - status: 'enqueued', - result: null, + status: skill.status, + result: { + text: skill.result, + reactions: [], + }, skillKey: skill.skillKey, args: skill.args, - }), - ), + costs: [], + }); + }), ); await _runNextActionIfNeeded(ctx, taskId); diff --git a/convex/action/public.ts b/convex/action/public.ts index fc5a828c..3c2eb7bf 100644 --- a/convex/action/public.ts +++ b/convex/action/public.ts @@ -26,6 +26,7 @@ export const act = mutation({ author: currentUser._id, owner: currentUser._id, shouldReopen, + status: 'enqueued', }); }, }); diff --git a/convex/magicRock.tsx b/convex/magicRock.tsx index e04f41ec..e99cfe1b 100644 --- a/convex/magicRock.tsx +++ b/convex/magicRock.tsx @@ -124,8 +124,29 @@ export async function _askMagicRock(args: MagicRockContext) { usage, warnings, providerMetadata, + reasoning, + reasoningDetails, + sources, + files, // - } = await generateText(args); + } = await generateText({ + ...args, + providerOptions: { + openrouter: { + reasoning: { effort: 'high' }, + provider: { + // only: ['baseten'], // "Not Found", no tools support + // only: ['novitaai'], // "Not Found", no tools support + // only: ['together'], // broken, possibly related to Harmony. + // only: ['fireworks'], // sort of works, but no nice. Possibly related to Harmony. + // only: ['parasail'], // "Not Found", no tools support + only: ['groq'], // the best yet, but not reliable. + allow_fallbacks: false, + require_parameters: true, + }, + }, + }, + }); const result = { finishReason, @@ -134,6 +155,10 @@ export async function _askMagicRock(args: MagicRockContext) { usage, warnings, providerMetadata, + reasoning, + reasoningDetails, + sources, + files, }; console.debug('askMagicRock', result); @@ -191,6 +216,12 @@ function languageModelFrom( // 'groq/llama-4-scout': groq('meta-llama/llama-4-scout-17b-16e-instruct'), // 'groq/llama-4-maverick': groq('meta-llama/llama-4-maverick-17b-128e-instruct'), 'groq/qwen3-32b': groq('qwen/qwen3-32b'), + 'openai/gpt-oss-120b': openrouter('openai/gpt-oss-120b', { + // reasoning: { enabled: false, effort: 'high' }, + }), + // 'openai/gpt-oss-20b': openrouter('openai/gpt-oss-20b', { + // // reasoning: { enabled: false, effort: 'high' }, + // }), // DeepSeek 'deepseek/deepseek-v3': deepseek('deepseek-chat'), diff --git a/convex/schedules/lifecycle.ts b/convex/schedules/lifecycle.ts index 7196d516..fe72f352 100644 --- a/convex/schedules/lifecycle.ts +++ b/convex/schedules/lifecycle.ts @@ -28,6 +28,7 @@ export const _executeOneTime = internalMutation({ skillKey, args, depth, + status: 'enqueued', }); await ctx.db.delete(scheduleId); @@ -55,6 +56,7 @@ export const _executeRecurring = internalMutation({ skillKey, args, depth, + status: 'enqueued', }); const nextRunAt = computeNextRun(cronExpression, timeZone); diff --git a/convex/schemas/actionSchema.tsx b/convex/schemas/actionSchema.tsx index 4734e391..913077c4 100644 --- a/convex/schemas/actionSchema.tsx +++ b/convex/schemas/actionSchema.tsx @@ -10,6 +10,8 @@ export const newActionSchema = z.object({ skillKey: z.string().describe('The key of the skill to use'), args: z.record(z.any()), depth: z.number().min(0).max(1000), + status: z.enum(['enqueued', 'succeeded']).default('enqueued'), + result: z.string().optional(), }); const coreActionSchema = z.object({ diff --git a/convex/schemas/skillSchema.tsx b/convex/schemas/skillSchema.tsx index 1bf0879c..2bde71b9 100644 --- a/convex/schemas/skillSchema.tsx +++ b/convex/schemas/skillSchema.tsx @@ -82,6 +82,8 @@ export const modelsSchema = z.enum([ // 'groq/llama-4-scout', // 'groq/llama-4-maverick', 'groq/qwen3-32b', + 'openai/gpt-oss-120b', + // 'openai/gpt-oss-20b', // DeepSeek 'deepseek/deepseek-v3', @@ -160,6 +162,10 @@ export function pricingFor(model: z.infer): { // return pricePerMillionTokens({ input: 0.2, output: 0.6 }); case 'groq/qwen3-32b': return pricePerMillionTokens({ input: 0.29, output: 0.59 }); + case 'openai/gpt-oss-120b': + return pricePerMillionTokens({ input: 0.25, output: 0.75 }); + // case 'openai/gpt-oss-20b': + // return pricePerMillionTokens({ input: 0.1, output: 0.5 }); // DeepSeek case 'deepseek/deepseek-v3': diff --git a/convex/skills/createAITool.ts b/convex/skills/createAITool.ts index be6affc8..235ede8b 100644 --- a/convex/skills/createAITool.ts +++ b/convex/skills/createAITool.ts @@ -40,6 +40,10 @@ export function createAITool( usage, warnings, providerMetadata, + reasoning, + reasoningDetails, + sources, + files, // } = await _askMagicRock(context); @@ -55,6 +59,7 @@ export function createAITool( author: action._id, owner: task.owner, depth: action.depth + 1, + status: 'enqueued', }); let reason = finishReason; @@ -65,6 +70,19 @@ export function createAITool( ); } + if (reasoning) { + reactions.push({ + skillKey: 'reason', + args: { reasoning }, + taskId: task._id, + author: action._id, + owner: task.owner, + depth: action.depth + 1, + status: 'succeeded', + result: reasoning, + }); + } + switch (reason) { // case 'tool-calls': @@ -94,6 +112,7 @@ export function createAITool( author: action._id, owner: task.owner, depth: action.depth + 1, + status: 'enqueued', }); break; @@ -101,7 +120,7 @@ export function createAITool( case 'stop': say(text); break; // prettier-ignore - case 'error': say(text); break; + case 'error': say(`Error: ${text}`); break; // prettier-ignore case 'content-filter': say(`[damn @sama] Content filter hit: ${warnings}`); break; diff --git a/convex/skills/createReactions.ts b/convex/skills/createReactions.ts index b09baa57..72d6bf11 100644 --- a/convex/skills/createReactions.ts +++ b/convex/skills/createReactions.ts @@ -1,4 +1,6 @@ +import { z } from 'zod'; import { Doc, Id } from '../_generated/dataModel'; +import { newActionSchema } from '../schemas/actionSchema'; export function createReactions( action: Doc<'actions'>, @@ -7,7 +9,8 @@ export function createReactions( args: Record; condition?: 'owner' | 'companion' | 'any'; }>, -) { +): Array> { + // return (reactions ?? []) .filter((reaction) => { // prettier-ignore @@ -24,5 +27,6 @@ export function createReactions( owner: action.owner, depth: action.depth + 1, author: action._id as Id<'actions'> | Id<'users'>, // I have no idea why I need that cast, as it expects a union of Id<'actions'> or Id<'users'> + status: 'enqueued' as const, })); } diff --git a/convex/skills/public.ts b/convex/skills/public.ts index d4812059..1470f8b3 100644 --- a/convex/skills/public.ts +++ b/convex/skills/public.ts @@ -107,6 +107,18 @@ export const availableIntelligences = query({ return { default: env.DEFAULT_MODEL, recommended: [ + { + key: 'openai/gpt-oss-120b', + name: 'GPT-OSS 120B', + provider: 'OpenAI', + description: 'Best performance per energy', + }, + // { + // key: 'openai/gpt-oss-20b', + // name: 'GPT-OSS 20B', + // provider: 'OpenAI', + // description: 'Best performance per energy', + // }, { key: 'anthropic/claude-4-sonnet', name: 'Claude 4 Sonnet', @@ -131,19 +143,38 @@ export const availableIntelligences = query({ provider: 'Anthropic', description: 'Surprisingly very good', }, - { - key: 'groq/qwen3-32b', - name: 'Qwen 32B', - provider: 'Groq', - description: 'Cheap and faaaast, a bit dumb', - }, ], all: [ + { + key: 'openrouter/qwen-3-coder', + name: 'Qwen 3 Coder', + provider: 'OpenRouter', + }, + { + key: 'openrouter/GLM-4.5-Air', + name: 'GLM 4.5 Air', + provider: 'OpenRouter', + }, + { + key: 'openrouter/GLM-4.5', + name: 'GLM 4.5', + provider: 'OpenRouter', + }, + { + key: 'deepinfra/glm-4.5', + name: 'GLM 4.5', + provider: 'DeepInfra', + }, { key: 'cerebras/qwen3-235b', name: 'Qwen 235B', provider: 'Cerebras', }, + { + key: 'groq/qwen3-32b', + name: 'Qwen 32B', + provider: 'Groq', + }, { key: 'anthropic/claude-4-opus', name: 'Claude 4 Opus', diff --git a/convex/tasks/private.ts b/convex/tasks/private.ts index c4eea6b3..dd415142 100644 --- a/convex/tasks/private.ts +++ b/convex/tasks/private.ts @@ -131,12 +131,14 @@ export const _add = internalMutation({ { skillKey: 'increaseBudget', args: { amount: initialFunds, shouldIterate: false }, + status: 'enqueued' as const, }, ] : []), { skillKey: 'say', args: { message }, + status: 'enqueued' as const, }, ]; @@ -164,6 +166,8 @@ export const _addWithActions = internalMutation({ z.object({ skillKey: z.string().describe('The key of the skill to use'), args: z.record(z.any()), + status: z.enum(['enqueued', 'succeeded']), + result: z.string().optional(), }), ), }, diff --git a/convex/users/private.ts b/convex/users/private.ts index 52066081..6c25bf4d 100644 --- a/convex/users/private.ts +++ b/convex/users/private.ts @@ -88,10 +88,12 @@ I'm also curious about Meseeks and would love to learn more about its capabiliti amount: asBigInt({ dollars: 1 }), shouldIterate: false, }, + status: 'enqueued' as const, }, { skillKey: 'lookAtMe', args: {}, + status: 'enqueued' as const, }, ], }); From 674448eb380b59e59d877586bcad1091348209d9 Mon Sep 17 00:00:00 2001 From: Igor Silva Date: Mon, 11 Aug 2025 14:21:15 +0100 Subject: [PATCH 2/2] gpt-5 --- bun.lockb | Bin 657243 -> 657776 bytes convex/magicRock.tsx | 13 ++++++++++--- convex/schemas/actionSchema.tsx | 2 +- convex/schemas/skillSchema.tsx | 11 +++++++++-- convex/skills/public.ts | 18 ++++++++++++++++++ package.json | 2 +- 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/bun.lockb b/bun.lockb index bb035711694f10794c6ed7b44076dac9a0b176bc..e648f205a7310567213461c1ce0ad111dfa22e66 100755 GIT binary patch delta 36455 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 diff --git a/convex/magicRock.tsx b/convex/magicRock.tsx index fdfe2a1e..579e4c2e 100644 --- a/convex/magicRock.tsx +++ b/convex/magicRock.tsx @@ -132,6 +132,10 @@ export async function _askMagicRock(args: MagicRockContext) { } = await generateText({ ...args, providerOptions: { + openai: { + reasoningEffort: 'high', + reasoningSummary: 'detailed', + }, openrouter: { reasoning: { effort: 'high' }, provider: { @@ -199,6 +203,9 @@ function languageModelFrom( // OpenAI // 'openai/gpt-4o': openai('gpt-4o', openAIconfig), // 'openai/gpt-4o-mini': openai('gpt-4o-mini', openAIconfig), + 'openai/gpt-5': openai('gpt-5', openAIconfig), + 'openai/gpt-5-mini': openai('gpt-5-mini', openAIconfig), + 'openai/gpt-5-nano': openai('gpt-5-nano', openAIconfig), 'openai/gpt-4.1': openai('gpt-4.1', openAIconfig), 'openai/gpt-4.1-mini': openai('gpt-4.1-mini', openAIconfig), 'openai/gpt-4.1-nano': openai('gpt-4.1-nano', openAIconfig), @@ -218,9 +225,9 @@ function languageModelFrom( // 'groq/llama-4-scout': groq('meta-llama/llama-4-scout-17b-16e-instruct'), // 'groq/llama-4-maverick': groq('meta-llama/llama-4-maverick-17b-128e-instruct'), 'groq/qwen3-32b': groq('qwen/qwen3-32b'), - 'openai/gpt-oss-120b': openrouter('openai/gpt-oss-120b', { - // reasoning: { enabled: false, effort: 'high' }, - }), + // 'openai/gpt-oss-120b': openrouter('openai/gpt-oss-120b', { + // // reasoning: { enabled: false, effort: 'high' }, + // }), // 'openai/gpt-oss-20b': openrouter('openai/gpt-oss-20b', { // // reasoning: { enabled: false, effort: 'high' }, // }), diff --git a/convex/schemas/actionSchema.tsx b/convex/schemas/actionSchema.tsx index 0ed0dde0..913077c4 100644 --- a/convex/schemas/actionSchema.tsx +++ b/convex/schemas/actionSchema.tsx @@ -10,7 +10,7 @@ export const newActionSchema = z.object({ skillKey: z.string().describe('The key of the skill to use'), args: z.record(z.any()), depth: z.number().min(0).max(1000), - status: z.enum(['enqueued', 'succeeded']).default('enqueued').optional(), + status: z.enum(['enqueued', 'succeeded']).default('enqueued'), result: z.string().optional(), }); diff --git a/convex/schemas/skillSchema.tsx b/convex/schemas/skillSchema.tsx index 0017f9f9..a9c7190d 100644 --- a/convex/schemas/skillSchema.tsx +++ b/convex/schemas/skillSchema.tsx @@ -68,6 +68,9 @@ export const modelsSchema = z.enum([ 'openai/gpt-4.1', 'openai/gpt-4.1-mini', 'openai/gpt-4.1-nano', + 'openai/gpt-5', + 'openai/gpt-5-mini', + 'openai/gpt-5-nano', 'openai/gpt-oss-120b', 'openai/gpt-oss-20b', @@ -142,6 +145,12 @@ export function pricingFor(model: z.infer): { return pricePerMillionTokens({ input: 0.4, output: 1.6 }); case 'openai/gpt-4.1-nano': return pricePerMillionTokens({ input: 0.1, output: 0.4 }); + case 'openai/gpt-5': + return pricePerMillionTokens({ input: 1.25, output: 10 }); + case 'openai/gpt-5-mini': + return pricePerMillionTokens({ input: 0.25, output: 2 }); + case 'openai/gpt-5-nano': + return pricePerMillionTokens({ input: 0.05, output: 0.4 }); case 'openai/gpt-oss-120b': return pricePerMillionTokens({ input: 0.25, output: 0.75 }); case 'openai/gpt-oss-20b': @@ -168,8 +177,6 @@ export function pricingFor(model: z.infer): { // return pricePerMillionTokens({ input: 0.2, output: 0.6 }); case 'groq/qwen3-32b': return pricePerMillionTokens({ input: 0.29, output: 0.59 }); - case 'openai/gpt-oss-120b': - return pricePerMillionTokens({ input: 0.25, output: 0.75 }); // case 'openai/gpt-oss-20b': // return pricePerMillionTokens({ input: 0.1, output: 0.5 }); diff --git a/convex/skills/public.ts b/convex/skills/public.ts index c9983647..07d0b8ad 100644 --- a/convex/skills/public.ts +++ b/convex/skills/public.ts @@ -107,6 +107,24 @@ export const availableIntelligences = query({ return { default: env.DEFAULT_MODEL, recommended: [ + { + key: 'openai/gpt-5', + name: 'GPT-5', + provider: 'OpenAI', + description: 'Best performance per energy', + }, + { + key: 'openai/gpt-5-mini', + name: 'GPT-5 Mini', + provider: 'OpenAI', + description: 'Best performance per energy', + }, + { + key: 'openai/gpt-5-nano', + name: 'GPT-5 Nano', + provider: 'OpenAI', + description: 'Best performance per energy', + }, { key: 'openai/gpt-oss-120b', name: 'GPT-OSS 120B', diff --git a/package.json b/package.json index 2daf0e57..9761008e 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@vercel/analytics": "^1.4.1", "@vercel/speed-insights": "^1.1.0", "@vitejs/plugin-react": "^4.3.4", - "ai": "^4.3.9", + "ai": "^4.3.19", "caniuse-lite": "^1.0.30001721", "class-variance-authority": "^0.7.1", "clsx": "1.2.1",