Preset custom_instructions rows are not client-writable, yet the phone runs every command with the row's prompt. sync_set_builtin_instruction_prompt_v1 changes only the prompt of the caller's preset (NULL restores the default), sync_list_builtin_instructions_v1 reports whether each prompt is the default, and the defaults live in one function.
101 lines
3.7 KiB
PL/PgSQL
101 lines
3.7 KiB
PL/PgSQL
-- Preset command prompts edited on the desktop reach the phone.
|
|
--
|
|
-- Built-in custom_instructions rows are not writable by clients (RLS allows
|
|
-- only builtin_key IS NULL), and the phone executes every command with the
|
|
-- row's prompt. These RPCs let the owner change only the prompt of their own
|
|
-- preset row, or restore its default; name, key and order stay server-owned.
|
|
-- Defaults live in one function that bootstrap_custom_instructions' values
|
|
-- mirror, so "is this the default?" has a single answer.
|
|
|
|
BEGIN;
|
|
|
|
CREATE OR REPLACE FUNCTION public.builtin_instruction_default_prompt_v1(p_builtin_key text)
|
|
RETURNS text
|
|
LANGUAGE sql
|
|
IMMUTABLE
|
|
SET search_path = ''
|
|
AS $$
|
|
SELECT CASE p_builtin_key
|
|
WHEN 'translate_en' THEN 'Translate the following text into natural English. Return only the translation.'
|
|
WHEN 'summarize' THEN 'Summarize the following text in no more than three concise lines.'
|
|
WHEN 'formal' THEN 'Rewrite the following text in a formal business style while preserving its meaning. Return only the rewritten text.'
|
|
WHEN 'explain_code' THEN 'Explain the following code in Korean, including its responsibilities and important caveats.'
|
|
END
|
|
$$;
|
|
|
|
REVOKE ALL ON FUNCTION public.builtin_instruction_default_prompt_v1(text) FROM PUBLIC, anon;
|
|
GRANT EXECUTE ON FUNCTION public.builtin_instruction_default_prompt_v1(text) TO authenticated;
|
|
|
|
-- p_prompt NULL (or blank) restores the default prompt.
|
|
CREATE OR REPLACE FUNCTION public.sync_set_builtin_instruction_prompt_v1(
|
|
p_builtin_key text,
|
|
p_prompt text DEFAULT NULL
|
|
)
|
|
RETURNS public.custom_instructions
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path = pg_catalog, public, auth
|
|
AS $$
|
|
DECLARE
|
|
actor_id uuid := auth.uid();
|
|
default_prompt text := public.builtin_instruction_default_prompt_v1(p_builtin_key);
|
|
next_prompt text;
|
|
saved public.custom_instructions;
|
|
BEGIN
|
|
IF actor_id IS NULL THEN
|
|
RAISE EXCEPTION 'authentication_required' USING ERRCODE = '42501';
|
|
END IF;
|
|
IF default_prompt IS NULL THEN
|
|
RAISE EXCEPTION 'invalid_builtin_key' USING ERRCODE = '22023';
|
|
END IF;
|
|
|
|
next_prompt := coalesce(nullif(btrim(p_prompt), ''), default_prompt);
|
|
IF char_length(next_prompt) > 4000 THEN
|
|
RAISE EXCEPTION 'invalid_instruction_prompt' USING ERRCODE = '22023';
|
|
END IF;
|
|
|
|
-- The preset rows are created lazily; make sure this user has them.
|
|
PERFORM public.bootstrap_custom_instructions();
|
|
|
|
UPDATE public.custom_instructions
|
|
SET prompt = next_prompt
|
|
WHERE user_id = actor_id
|
|
AND builtin_key = p_builtin_key
|
|
AND prompt IS DISTINCT FROM next_prompt
|
|
RETURNING * INTO saved;
|
|
|
|
IF saved.id IS NULL THEN
|
|
SELECT * INTO saved
|
|
FROM public.custom_instructions
|
|
WHERE user_id = actor_id AND builtin_key = p_builtin_key;
|
|
END IF;
|
|
RETURN saved;
|
|
END;
|
|
$$;
|
|
|
|
REVOKE ALL ON FUNCTION public.sync_set_builtin_instruction_prompt_v1(text, text) FROM PUBLIC, anon;
|
|
GRANT EXECUTE ON FUNCTION public.sync_set_builtin_instruction_prompt_v1(text, text) TO authenticated;
|
|
|
|
-- Preset rows with a flag telling whether the prompt is still the default.
|
|
CREATE OR REPLACE FUNCTION public.sync_list_builtin_instructions_v1()
|
|
RETURNS TABLE (builtin_key text, prompt text, is_default boolean, updated_at timestamptz)
|
|
LANGUAGE sql
|
|
STABLE
|
|
SECURITY INVOKER
|
|
SET search_path = ''
|
|
AS $$
|
|
SELECT
|
|
instruction.builtin_key,
|
|
instruction.prompt,
|
|
instruction.prompt = public.builtin_instruction_default_prompt_v1(instruction.builtin_key),
|
|
instruction.updated_at
|
|
FROM public.custom_instructions AS instruction
|
|
WHERE instruction.user_id = auth.uid()
|
|
AND instruction.builtin_key IS NOT NULL
|
|
ORDER BY instruction.sort_order
|
|
$$;
|
|
|
|
REVOKE ALL ON FUNCTION public.sync_list_builtin_instructions_v1() FROM PUBLIC, anon;
|
|
GRANT EXECUTE ON FUNCTION public.sync_list_builtin_instructions_v1() TO authenticated;
|
|
|
|
COMMIT;
|