mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-21 13:00:04 +08:00
fix(cli): name SIM_CONFIG_DIR in help, and fix the similarity score width (#6795)
Two loose ends from the command-surface audit. `--help` stated where the profile files live and named only `~/.sim`, so it was wrong for anyone who had set `SIM_CONFIG_DIR` — which every CI job pointing the CLI at a scratch directory has. The variable is documented in the README and the guides; help was the one place that omitted it. `knowledge search` printed the raw similarity double, `0.2818957269585687`: a nineteen-character column whose last dozen digits cannot separate one result from another. A `score` format fixes it to four decimals, the width `cost` already uses, so the column stays put down the page. `json` and `yaml` still carry the full double, which is what a script compares.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
import type { Command } from 'commander'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { V2_OPERATIONS, type V2OperationName } from '../generated/v2-api'
|
||||
import { HELP_EPILOGUE } from '../program'
|
||||
import { buildGeneratedCommands } from '../runtime/build'
|
||||
import { flagNameFor, flagSpecFor } from '../runtime/request'
|
||||
import type { OperationSpec } from '../runtime/types'
|
||||
@@ -193,4 +194,12 @@ describe('folder-path fields', () => {
|
||||
expect(paths).toContain('serviceId')
|
||||
expect(paths).toContain('providerId')
|
||||
})
|
||||
|
||||
it('mentions the variable that moves the profile files, since help names a path', () => {
|
||||
// The epilogue states where the files live, and SIM_CONFIG_DIR moves both.
|
||||
// Naming only ~/.sim made help wrong for anyone who had set it — including
|
||||
// every CI job that points the CLI at a scratch directory.
|
||||
expect(HELP_EPILOGUE).toContain('~/.sim/config')
|
||||
expect(HELP_EPILOGUE).toContain('SIM_CONFIG_DIR')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -259,7 +259,7 @@ export const CLI_CONTRACT: CliContract = {
|
||||
},
|
||||
itemsPath: 'results',
|
||||
columns: [
|
||||
{ header: 'score', path: 'similarity' },
|
||||
{ header: 'score', path: 'similarity', format: 'score' },
|
||||
{ header: 'document', path: 'documentName' },
|
||||
{ header: 'chunk', path: 'chunkIndex' },
|
||||
{ header: 'content' },
|
||||
|
||||
@@ -123,6 +123,10 @@ export interface ColumnSpec {
|
||||
* wire encoding for the human formats, so a folder no longer prints as
|
||||
* `/cli-test-a/nested%20one` in the same row as the `nested one` the server
|
||||
* put in the adjacent name column.
|
||||
*
|
||||
* `score` fixes a similarity to four decimals. The raw double arrives as
|
||||
* `0.2818957269585687`, a nineteen-character column whose last dozen digits
|
||||
* cannot separate one result from another.
|
||||
*/
|
||||
format?:
|
||||
| 'auto'
|
||||
@@ -134,6 +138,7 @@ export interface ColumnSpec {
|
||||
| 'count'
|
||||
| 'trace-count'
|
||||
| 'folder-path'
|
||||
| 'score'
|
||||
}
|
||||
|
||||
export interface BodyVariantSpec {
|
||||
|
||||
@@ -13,7 +13,8 @@ export const PROGRAM_DESCRIPTION = 'Talk to the Sim API from your terminal'
|
||||
|
||||
export const HELP_EPILOGUE = `
|
||||
Profiles work like the AWS CLI: settings live in ~/.sim/config, keys in
|
||||
~/.sim/credentials (0600). Select one with -P, --profile, or SIM_PROFILE.
|
||||
~/.sim/credentials (0600), or under SIM_CONFIG_DIR when it is set. Select one
|
||||
with -P, --profile, or SIM_PROFILE.
|
||||
|
||||
Examples:
|
||||
$ sim login Authorize the default profile
|
||||
|
||||
@@ -881,7 +881,9 @@ describe('contract-selected list rendering', () => {
|
||||
totalResults: 1,
|
||||
})
|
||||
|
||||
expect(printed).toEqual(['0.91\tpolicy.md\t2\tRefunds are available for 30 days.'])
|
||||
// Four decimals, fixed, like the `cost` column: a similarity is compared
|
||||
// against its neighbours, so the width has to stay put down the column.
|
||||
expect(printed).toEqual(['0.9100\tpolicy.md\t2\tRefunds are available for 30 days.'])
|
||||
})
|
||||
|
||||
it('renders row matches as rows', async () => {
|
||||
|
||||
@@ -172,6 +172,29 @@ describe('a declared field that the API stops returning', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('a similarity score, at a width a person can read', () => {
|
||||
const results = {
|
||||
results: [
|
||||
{ similarity: 0.2818957269585687, documentName: 'a.md', chunkIndex: 0, content: 'x' },
|
||||
],
|
||||
}
|
||||
const spec = CLI_CONTRACT.searchKnowledge as CommandSpec
|
||||
|
||||
it('fixes the score to four decimals in the table', () => {
|
||||
// The raw double is nineteen characters wide and its last dozen digits
|
||||
// separate nothing: every row shares them to within a rounding error.
|
||||
renderResult('searchKnowledge', 'table', results, spec)
|
||||
const [, row] = tableLines()
|
||||
expect(row).toContain('0.2819')
|
||||
expect(row).not.toContain('0.2818957269585687')
|
||||
})
|
||||
|
||||
it('leaves the full double in json, which is what a script compares', () => {
|
||||
renderResult('searchKnowledge', 'json', results, spec)
|
||||
expect(JSON.parse(logged[0]).results[0].similarity).toBe(0.2818957269585687)
|
||||
})
|
||||
})
|
||||
|
||||
describe('folder paths are shown by name, but piped in wire form', () => {
|
||||
const folders = [
|
||||
{
|
||||
|
||||
@@ -80,6 +80,8 @@ function renderCell(
|
||||
return bool(value as boolean | null)
|
||||
case 'cost':
|
||||
return typeof value === 'number' ? `$${value.toFixed(4)}` : text(null)
|
||||
case 'score':
|
||||
return typeof value === 'number' ? value.toFixed(4) : text(null)
|
||||
case 'count':
|
||||
return Array.isArray(value) ? String(value.length) : text(null)
|
||||
case 'folder-path':
|
||||
|
||||
Reference in New Issue
Block a user