Packages
phoenix_kit
1.7.112
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/migrations/postgres/v41.ex
defmodule PhoenixKit.Migrations.Postgres.V41 do
@moduledoc """
PhoenixKit V41 Migration: AI Request Prompt Tracking & Reasoning Parameters
This migration adds:
1. Prompt tracking columns to AI requests table
2. Reasoning/thinking parameters to AI endpoints table
## Changes
### Modified Table: phoenix_kit_ai_requests
- Added prompt_id for linking requests to prompts
- Added prompt_name for denormalized history display (like endpoint_name)
### Modified Table: phoenix_kit_ai_endpoints
- Added reasoning_enabled (boolean) - Enable reasoning with default effort
- Added reasoning_effort (string) - none/minimal/low/medium/high/xhigh
- Added reasoning_max_tokens (integer) - Hard cap on thinking tokens (1024-32000)
- Added reasoning_exclude (boolean) - Hide reasoning from response
## Backward Compatibility
- Existing requests will have NULL prompt_id/prompt_name (not all requests use prompts)
- Foreign key uses ON DELETE SET NULL to preserve history when prompts are deleted
- Existing endpoints will have NULL reasoning values (reasoning disabled by default)
"""
use Ecto.Migration
def up(opts) do
prefix = Map.get(opts, :prefix, "public")
# Check if AI requests table exists (module may not be enabled)
if table_exists?(:phoenix_kit_ai_requests, prefix) do
# Add prompt tracking columns to requests table
alter table(:phoenix_kit_ai_requests, prefix: prefix) do
add_if_not_exists :prompt_id, :integer
add_if_not_exists :prompt_name, :string, size: 255
end
# Index for prompt_id
create_if_not_exists index(:phoenix_kit_ai_requests, [:prompt_id],
name: :phoenix_kit_ai_requests_prompt_id_idx,
prefix: prefix
)
# Foreign key constraint (only if prompts table exists)
if table_exists?(:phoenix_kit_ai_prompts, prefix) do
execute """
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'phoenix_kit_ai_requests_prompt_id_fkey'
AND conrelid = '#{prefix_table_name("phoenix_kit_ai_requests", prefix)}'::regclass
) THEN
ALTER TABLE #{prefix_table_name("phoenix_kit_ai_requests", prefix)}
ADD CONSTRAINT phoenix_kit_ai_requests_prompt_id_fkey
FOREIGN KEY (prompt_id)
REFERENCES #{prefix_table_name("phoenix_kit_ai_prompts", prefix)}(id)
ON DELETE SET NULL;
END IF;
END $$;
"""
end
# Add column comments
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_requests", prefix)}.prompt_id IS
'Reference to AI prompt used (if request was made via ask_with_prompt or similar)'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_requests", prefix)}.prompt_name IS
'Denormalized prompt name for historical display'
"""
end
# Add reasoning columns to endpoints table
if table_exists?(:phoenix_kit_ai_endpoints, prefix) do
alter table(:phoenix_kit_ai_endpoints, prefix: prefix) do
add_if_not_exists :reasoning_enabled, :boolean
add_if_not_exists :reasoning_effort, :string, size: 20
add_if_not_exists :reasoning_max_tokens, :integer
add_if_not_exists :reasoning_exclude, :boolean
end
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_endpoints", prefix)}.reasoning_enabled IS
'Enable reasoning/thinking mode with default (medium) effort'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_endpoints", prefix)}.reasoning_effort IS
'Reasoning intensity: none, minimal, low, medium, high, xhigh'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_endpoints", prefix)}.reasoning_max_tokens IS
'Hard cap on reasoning/thinking tokens (1024-32000)'
"""
execute """
COMMENT ON COLUMN #{prefix_table_name("phoenix_kit_ai_endpoints", prefix)}.reasoning_exclude IS
'Hide reasoning from response while still using it internally'
"""
end
# Update version
execute "COMMENT ON TABLE #{prefix_table_name("phoenix_kit", prefix)} IS '41'"
end
def down(opts) do
prefix = Map.get(opts, :prefix, "public")
if table_exists?(:phoenix_kit_ai_requests, prefix) do
# Drop foreign key constraint
execute """
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM pg_constraint
WHERE conname = 'phoenix_kit_ai_requests_prompt_id_fkey'
AND conrelid = '#{prefix_table_name("phoenix_kit_ai_requests", prefix)}'::regclass
) THEN
ALTER TABLE #{prefix_table_name("phoenix_kit_ai_requests", prefix)}
DROP CONSTRAINT phoenix_kit_ai_requests_prompt_id_fkey;
END IF;
END $$;
"""
# Drop index
drop_if_exists index(:phoenix_kit_ai_requests, [:prompt_id],
name: :phoenix_kit_ai_requests_prompt_id_idx,
prefix: prefix
)
# Remove columns
alter table(:phoenix_kit_ai_requests, prefix: prefix) do
remove_if_exists :prompt_id, :integer
remove_if_exists :prompt_name, :string
end
end
# Remove reasoning columns from endpoints table
if table_exists?(:phoenix_kit_ai_endpoints, prefix) do
alter table(:phoenix_kit_ai_endpoints, prefix: prefix) do
remove_if_exists :reasoning_enabled, :boolean
remove_if_exists :reasoning_effort, :string
remove_if_exists :reasoning_max_tokens, :integer
remove_if_exists :reasoning_exclude, :boolean
end
end
# Update version
execute "COMMENT ON TABLE #{prefix_table_name("phoenix_kit", prefix)} IS '40'"
end
# Helper to check if a table exists
defp table_exists?(table_name, prefix) do
query = """
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = '#{prefix}'
AND table_name = '#{table_name}'
)
"""
%{rows: [[exists]]} = PhoenixKit.RepoHelper.repo().query!(query)
exists
end
defp prefix_table_name(table, "public"), do: "public.#{table}"
defp prefix_table_name(table, prefix), do: "#{prefix}.#{table}"
end