feat(selection): persist retrieval preference
This commit is contained in:
1 parent
151306a6cc
commit
bfbe001248
7 files changed
+24
-8
No files matched your search
@@ -15,7 +15,7 @@ function Read-InstallBoolean {
|
||||
|
||||
function Read-InstallOptions {
|
||||
param([string]$HomePath, [string]$RepositoryRoot, [string]$Client, [switch]$DryRun)
|
||||
$defaults = @{ update_agents = $false; flashbang = $true }
|
||||
$defaults = @{ update_agents = $false; flashbang = $true; semantic_retrieval = $false }
|
||||
if (Test-Path -LiteralPath (Join-Path $HomePath '.my-ai-configuration/selection.json')) {
|
||||
try { $defaults = Read-UpdateSelection -HomePath $HomePath -RepositoryRoot $RepositoryRoot -AllowLegacy }
|
||||
catch { Write-Warning 'Saved options could not be read; confirm new options below.' }
|
||||
@@ -24,6 +24,7 @@ function Read-InstallOptions {
|
||||
return @{
|
||||
update_agents = Read-InstallBoolean -Prompt "Update selected agent CLIs ($Client)?" -Default $defaults.update_agents
|
||||
flashbang = Read-InstallBoolean -Prompt 'Enable the Flashbang notification hook?' -Default $defaults.flashbang
|
||||
semantic_retrieval = Read-InstallBoolean -Prompt 'Enable Qwen3-Embedding-0.6B semantic retrieval?' -Default $defaults.semantic_retrieval
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,13 @@ read_install_boolean() {
|
||||
read_install_options() {
|
||||
update_agents=false
|
||||
flashbang=true
|
||||
semantic_retrieval=false
|
||||
local saved key value
|
||||
if [ -f "$home_path/.my-ai-configuration/selection.json" ]; then
|
||||
if saved=$(python3 "$root/scripts/lib/selection-state.py" read --home "$home_path" --manifest "$root/adapters/plugins.tsv" --format tsv --allow-legacy); then
|
||||
while IFS=$'\t' read -r key value; do
|
||||
value=${value%$'\r'}
|
||||
case "$key" in update_agents) update_agents=$value ;; flashbang) flashbang=$value ;; esac
|
||||
case "$key" in update_agents) update_agents=$value ;; flashbang) flashbang=$value ;; semantic_retrieval) semantic_retrieval=$value ;; esac
|
||||
done <<< "$saved"
|
||||
else
|
||||
printf 'WARN Saved options could not be read; confirm new options below.\n' >&2
|
||||
@@ -32,6 +33,7 @@ read_install_options() {
|
||||
[ "$dry_run" = false ] || return 0
|
||||
update_agents=$(read_install_boolean "Update selected agent CLIs ($client)?" "$update_agents") || return
|
||||
flashbang=$(read_install_boolean 'Enable the Flashbang notification hook?' "$flashbang") || return
|
||||
semantic_retrieval=$(read_install_boolean 'Enable Qwen3-Embedding-0.6B semantic retrieval?' "$semantic_retrieval") || return
|
||||
}
|
||||
|
||||
is_windows_host() {
|
||||
|
||||
@@ -9,8 +9,8 @@ function Read-UpdateSelection {
|
||||
|
||||
function Save-UpdateSelection {
|
||||
param([string]$HomePath, [string]$RepositoryRoot, [string]$Shell, [string]$Client, [hashtable]$Plugins,
|
||||
[Parameter(Mandatory=$true)][bool]$UpdateAgents, [Parameter(Mandatory=$true)][bool]$Flashbang)
|
||||
$arguments = @((Join-Path $PSScriptRoot 'selection-state.py'), 'write', '--home', $HomePath, '--manifest', (Join-Path $RepositoryRoot 'adapters/plugins.tsv'), '--shell', $Shell.ToLowerInvariant(), '--client', $Client.ToLowerInvariant(), '--update-agents', $UpdateAgents.ToString().ToLowerInvariant(), '--flashbang', $Flashbang.ToString().ToLowerInvariant(), '--selected')
|
||||
[Parameter(Mandatory=$true)][bool]$UpdateAgents, [Parameter(Mandatory=$true)][bool]$Flashbang, [bool]$SemanticRetrieval = $false)
|
||||
$arguments = @((Join-Path $PSScriptRoot 'selection-state.py'), 'write', '--home', $HomePath, '--manifest', (Join-Path $RepositoryRoot 'adapters/plugins.tsv'), '--shell', $Shell.ToLowerInvariant(), '--client', $Client.ToLowerInvariant(), '--update-agents', $UpdateAgents.ToString().ToLowerInvariant(), '--flashbang', $Flashbang.ToString().ToLowerInvariant(), '--semantic-retrieval', $SemanticRetrieval.ToString().ToLowerInvariant(), '--selected')
|
||||
$arguments += @($Plugins.Selected | ForEach-Object { $_.name })
|
||||
$arguments += '--deselected'
|
||||
$arguments += @($Plugins.Deselected | ForEach-Object { $_.name })
|
||||
|
||||
@@ -18,7 +18,9 @@ def validate(state, allow_legacy=False):
|
||||
raise ValueError('Unsupported saved selection.')
|
||||
if state.get('shell') not in ('powershell', 'bash') or state.get('client') not in ('codex', 'claude', 'both'):
|
||||
raise ValueError('Invalid saved shell or client.')
|
||||
if any(type(state.get(key)) is not bool for key in ('update_agents', 'flashbang')):
|
||||
if 'semantic_retrieval' not in state:
|
||||
state['semantic_retrieval'] = False
|
||||
if any(type(state.get(key)) is not bool for key in ('update_agents', 'flashbang', 'semantic_retrieval')):
|
||||
raise ValueError('Invalid saved install options. Run update once without Quick.')
|
||||
for key in ('selected', 'deselected'):
|
||||
values = state.get(key)
|
||||
@@ -41,6 +43,7 @@ def main():
|
||||
parser.add_argument('--allow-legacy', action='store_true')
|
||||
parser.add_argument('--update-agents', choices=('true', 'false'))
|
||||
parser.add_argument('--flashbang', choices=('true', 'false'))
|
||||
parser.add_argument('--semantic-retrieval', choices=('true', 'false'))
|
||||
parser.add_argument('--client')
|
||||
parser.add_argument('--selected', nargs='*', default=[])
|
||||
parser.add_argument('--deselected', nargs='*', default=[])
|
||||
@@ -59,7 +62,7 @@ def main():
|
||||
else:
|
||||
print('shell\t' + state['shell'])
|
||||
print('client\t' + state['client'])
|
||||
for key in ('update_agents', 'flashbang'):
|
||||
for key in ('update_agents', 'flashbang', 'semantic_retrieval'):
|
||||
print(key + '\t' + str(state[key]).lower())
|
||||
for key in ('selected', 'deselected'):
|
||||
for name in state[key]:
|
||||
@@ -68,6 +71,7 @@ def main():
|
||||
state = validate(dict(version=2, shell=args.shell, client=args.client,
|
||||
update_agents=None if args.update_agents is None else args.update_agents == 'true',
|
||||
flashbang=None if args.flashbang is None else args.flashbang == 'true',
|
||||
semantic_retrieval=False if args.semantic_retrieval is None else args.semantic_retrieval == 'true',
|
||||
selected=args.selected, deselected=args.deselected))
|
||||
if (set(state['selected']) | set(state['deselected'])) - names:
|
||||
raise ValueError('Unknown plugin in selection.')
|
||||
|
||||
@@ -12,6 +12,7 @@ read_update_selection() {
|
||||
client) [ -n "$client" ] || client=$value ;;
|
||||
update_agents) update_agents=$value ;;
|
||||
flashbang) flashbang=$value ;;
|
||||
semantic_retrieval) semantic_retrieval=$value ;;
|
||||
selected) selected_plugins+=("$value") ;;
|
||||
deselected) deselected_plugins+=("$value") ;;
|
||||
esac
|
||||
@@ -20,6 +21,6 @@ read_update_selection() {
|
||||
|
||||
save_update_selection() {
|
||||
python3 "$root/scripts/lib/selection-state.py" write --home "$home_path" --manifest "$root/adapters/plugins.tsv" \
|
||||
--shell "$shell" --client "$client" --update-agents "$update_agents" --flashbang "$flashbang" \
|
||||
--shell "$shell" --client "$client" --update-agents "$update_agents" --flashbang "$flashbang" --semantic-retrieval "${semantic_retrieval:-false}" \
|
||||
--selected "${selected_plugins[@]}" --deselected "${deselected_plugins[@]}"
|
||||
}
|
||||
@@ -184,7 +184,7 @@ class InstallOptionsTests(unittest.TestCase):
|
||||
'select_configured_plugins() { :; }\nsync_configured_plugins() { :; }\n'
|
||||
'run_plugin_command() { printf "CLI-MOCK %s\\n" "$2"; }\n')
|
||||
environment = dict(os.environ, HOME=home.as_posix(), TEST_INSTALL_HOME=str(home))
|
||||
for name, quick, answers in [('install', False, 'y\nn\n'), ('update', True, '')]:
|
||||
for name, quick, answers in [('install', False, 'y\nn\nn\n'), ('update', True, '')]:
|
||||
entry = str(scripts / (name + '.' + suffix))
|
||||
command = ([executable, '-NoProfile', '-File', entry, '-Shell', 'Bash', '-Client', 'Both', '-Summary']
|
||||
if kind == 'powershell' else [executable, entry, '--shell', 'bash', '--client', 'both', '--summary'])
|
||||
|
||||
@@ -71,6 +71,14 @@ class SelectionTests(unittest.TestCase):
|
||||
self.path.write_text(json.dumps(state))
|
||||
self.assertNotEqual(self.run_state('read').returncode, 0)
|
||||
|
||||
def test_semantic_retrieval_option_round_trips(self):
|
||||
result = self.run_state('write', '--shell', 'bash', '--client', 'both', '--update-agents', 'false',
|
||||
'--flashbang', 'true', '--semantic-retrieval', 'true')
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
state = json.loads(self.run_state('read').stdout)
|
||||
self.assertTrue(state['semantic_retrieval'])
|
||||
self.assertIn('semantic_retrieval\ttrue', self.run_state('read', '--format', 'tsv').stdout)
|
||||
|
||||
def test_invalid_write_preserves_last_selection(self):
|
||||
self.save('--selected', 'Superpowers')
|
||||
original = self.path.read_bytes()
|
||||
|
||||
Reference in new issue
Block a user