thatgfsj-code 3.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjF,qBAAa,GAAG;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,UAAU,EAAE,eAAe,CAAC;IAC5B;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAS;IAE9B,OAAO;WAoBM,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;IAyCnC;;;;;;;;;;;;OAYG;IACI,cAAc,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC;IAkB1F;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CAgCnF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjF,qBAAa,GAAG;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,GAAG,EAAE,UAAU,CAAC;IAChB,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,UAAU,EAAE,eAAe,CAAC;IAC5B;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAS;IAE9B,OAAO;WAoBM,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;IAyCnC;;;;;;;;;;;;OAYG;IACI,cAAc,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,WAAW,EAAE,YAAY,CAAC;IA2B1F;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;CAgCnF"}
package/dist/app/index.js CHANGED
@@ -94,6 +94,7 @@ export class App {
94
94
  async *streamResponse(messages) {
95
95
  const msgs = messages || this.session.getMessages();
96
96
  const inner = this.llm.chatStream(msgs);
97
+ const debugUsage = !!process.env.GFCODE_DEBUG_USAGE;
97
98
  let next = await inner.next();
98
99
  while (!next.done) {
99
100
  // Forward chunks unchanged, but capture usage into the persistent
@@ -103,6 +104,12 @@ export class App {
103
104
  this.cacheStats.record(next.value.usage);
104
105
  }
105
106
  catch { /* best-effort */ }
107
+ if (debugUsage) {
108
+ // v3.0.0 DEBUG: dump raw usage fields to stderr so the user can
109
+ // confirm whether the upstream provider/relay forwards cache stats.
110
+ // Enable with: GFCODE_DEBUG_USAGE=1 gfcode ...
111
+ process.stderr.write('[debug_usage] ' + JSON.stringify(next.value.usage) + '\n');
112
+ }
106
113
  }
107
114
  yield next.value;
108
115
  next = await inner.next();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/app/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAA2C,MAAM,OAAO,CAAC;AAWhE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAO3C,UAAU,KAAK;IACb,GAAG,EAAE,GAAG,CAAC;CACV;AAkBD,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,qBA+JpC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAA2C,MAAM,OAAO,CAAC;AAWhE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAM3C,UAAU,KAAK;IACb,GAAG,EAAE,GAAG,CAAC;CACV;AAkBD,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,qBAiHpC"}
package/dist/tui/app.js CHANGED
@@ -36,8 +36,6 @@ export function TuiApp({ app }) {
36
36
  const { handleCommand } = useCommands(app);
37
37
  const [systemMessages, setSystemMessages] = useState([]);
38
38
  const [viewMode, setViewMode] = useState('chat');
39
- const [initProvider, setInitProvider] = useState('siliconflow');
40
- const [initUrl, setInitUrl] = useState('');
41
39
  const { stdout } = useStdout();
42
40
  const terminalWidth = stdout?.columns || 80;
43
41
  // v3.0.0: cache stats snapshot for the Header. Re-read whenever messages
@@ -51,44 +49,6 @@ export function TuiApp({ app }) {
51
49
  setSystemMessages(prev => [...prev, { role: 'assistant', content }]);
52
50
  }, []);
53
51
  const onSubmit = useCallback(async (input) => {
54
- // Init wizard - API Key input
55
- if (viewMode === 'init_key') {
56
- const key = input.trim();
57
- if (!key) {
58
- setViewMode('chat');
59
- return;
60
- }
61
- // Save and complete
62
- const { App: AppClass } = await import('../app/index.js');
63
- const cfg = app.config.get();
64
- app.config.save({ provider: initProvider, apiKey: key, model: cfg.model || 'default' });
65
- saveModelToHistory(cfg.model || 'default');
66
- setViewMode('chat');
67
- addMsg(`配置已更新: ${initProvider}`);
68
- return;
69
- }
70
- // Init wizard - Custom URL input
71
- if (viewMode === 'init_url') {
72
- const url = input.trim();
73
- if (!url) {
74
- setViewMode('chat');
75
- return;
76
- }
77
- setInitUrl(url);
78
- setViewMode('init_key');
79
- return;
80
- }
81
- // Init wizard - Custom model name
82
- if (viewMode === 'init_custom_model') {
83
- const model = input.trim();
84
- if (model) {
85
- app.config.save({ model });
86
- saveModelToHistory(model);
87
- addMsg(`模型已切换: ${model}`);
88
- }
89
- setViewMode('chat');
90
- return;
91
- }
92
52
  // Model selector - ignore text input
93
53
  if (viewMode === 'model_select')
94
54
  return;
@@ -114,19 +74,26 @@ export function TuiApp({ app }) {
114
74
  return;
115
75
  }
116
76
  sendMessage(input);
117
- }, [handleCommand, sendMessage, app, viewMode, initProvider, initUrl, addMsg]);
77
+ }, [handleCommand, sendMessage, app, viewMode, addMsg]);
118
78
  const allMessages = [...systemMessages, ...messages];
119
79
  const activeSkills = app.skills.listActive().map(s => s.id);
120
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { provider: app.config.get().provider, model: app.config.get().model, cacheHitRate: cacheSnapshot.hitRate > 0 ? cacheSnapshot.hitRate : null, cacheSavingsCNY: cacheSnapshot.estimatedSavingsCNY }), _jsx(ChatList, { messages: allMessages, streaming: streaming, streamingToolCalls: streamingToolCalls, width: terminalWidth - 4 }), _jsx(Thinking, { active: isThinking }), queuedMessage && (_jsxs(Box, { paddingLeft: 1, children: [_jsx(Text, { color: "#F59E0B", children: "\uD83D\uDCCE \u5DF2\u6392\u961F: " }), _jsx(Text, { color: "#94A3B8", children: queuedMessage })] })), viewMode === 'model_select' ? (_jsx(ModelSelector, { currentModel: app.config.get().model, onSelect: (model) => {
80
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Header, { provider: app.config.get().provider, model: app.config.get().model, cacheHitRate: cacheSnapshot.hitRate > 0 ? cacheSnapshot.hitRate : null, cacheSavingsCNY: cacheSnapshot.estimatedSavingsCNY }), _jsx(ChatList, { messages: allMessages, streaming: streaming, streamingToolCalls: streamingToolCalls, width: terminalWidth - 4 }), _jsx(Thinking, { active: isThinking }), queuedMessage && (_jsxs(Box, { paddingLeft: 1, children: [_jsx(Text, { color: "#F59E0B", children: "\uD83D\uDCCE \u5DF2\u6392\u961F: " }), _jsx(Text, { color: "#94A3B8", children: queuedMessage })] })), viewMode === 'model_select' ? (_jsx(ModelSelector, { currentModel: app.config.get().model, currentProvider: app.config.get().provider, onSelect: (model) => {
121
81
  app.config.save({ model });
122
82
  saveModelToHistory(model);
123
83
  setViewMode('chat');
124
84
  addMsg(`模型已切换: ${model}`);
125
- }, onAddNew: () => setViewMode('init_wizard') })) : viewMode === 'init_wizard' ? (_jsx(InitWizard, { onComplete: (provider, model, apiKey, baseUrl) => {
85
+ }, onAddNew: () => setViewMode('init_wizard') })) : viewMode === 'init_wizard' ? (
86
+ // v3.0.1: InitWizard is now fully self-contained — it owns its own
87
+ // input handling via useInput + ink-text-input. No external UserInput
88
+ // is rendered here, and app.tsx no longer has the text-entry
89
+ // viewModes (init_key / init_url / init_custom_model) because they
90
+ // were the broken input-handling path that left users stuck on a
91
+ // frozen "输入 API Key" screen with no way to type.
92
+ _jsx(InitWizard, { onComplete: (provider, model, apiKey, baseUrl) => {
126
93
  app.config.save({ provider, model, apiKey, baseUrl });
127
94
  saveModelToHistory(model);
128
95
  setViewMode('chat');
129
96
  addMsg(`配置完成: ${provider} / ${model}`);
130
- }, onCancel: () => setViewMode('chat') })) : (_jsxs(Box, { flexDirection: "column", children: [viewMode === 'init_key' && (_jsxs(Box, { paddingLeft: 1, marginBottom: 0, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165 API Key: " }), _jsxs(Text, { dimColor: true, children: ["(", initProvider, ")"] })] })), viewMode === 'init_url' && (_jsx(Box, { paddingLeft: 1, marginBottom: 0, children: _jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u4E2D\u8F6C\u7AD9 URL: " }) })), viewMode === 'init_custom_model' && (_jsx(Box, { paddingLeft: 1, marginBottom: 0, children: _jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u6A21\u578B\u540D\u79F0: " }) })), _jsx(UserInput, { onSubmit: onSubmit, onCancel: cancel, disabled: false })] })), _jsx(StatusBar, { messageCount: allMessages.length, skills: activeSkills })] }));
97
+ }, onCancel: () => setViewMode('chat') })) : (_jsx(Box, { flexDirection: "column", children: _jsx(UserInput, { onSubmit: onSubmit, onCancel: cancel, disabled: false }) })), _jsx(StatusBar, { messageCount: allMessages.length, skills: activeSkills })] }));
131
98
  }
132
99
  //# sourceMappingURL=app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tui/app.tsx"],"names":[],"mappings":"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"}
@@ -6,17 +6,26 @@ interface Props {
6
6
  onComplete: (provider: ProviderName, model: string, apiKey: string, baseUrl?: string) => void;
7
7
  onCancel: () => void;
8
8
  }
9
- type InitStep = 'provider' | 'api_key' | 'model' | 'custom_model' | 'custom_url' | 'cache_strategy' | 'cache_ttl';
9
+ type InitStep = 'provider' | 'custom_url' | 'api_key' | 'model' | 'custom_model' | 'cache_strategy' | 'cache_ttl';
10
10
  /**
11
- * v3.0.0: InitWizard gained two new steps after model selection:
12
- * - cache_strategy: enable / disable prompt caching
13
- * - cache_ttl: 5m vs 1h (only if enabled)
11
+ * v3.0.1: InitWizard is now fully self-contained it manages its own
12
+ * step state AND its own keyboard input for text-entry steps (api_key,
13
+ * custom_url, custom_model). The previous version had a fatal bug:
14
14
  *
15
- * The defaults mirror ConfigManager.DEFAULT_CONFIG (enabled, 5m). Users on
16
- * OpenAI / DeepSeek / Gemini can ignore these those providers do
17
- * automatic caching and the flag is purely advisory there. The flag
18
- * matters for Anthropic users who want to opt out of cache_control
19
- * markers or pick a longer TTL.
15
+ * The text-entry steps (`api_key`, `custom_url`, `custom_model`) only
16
+ * rendered a `<Text>` prompt with no actual input box. The host
17
+ * component (app.tsx) had its own UserInput BUT only rendered it when
18
+ * viewMode was NOT 'init_wizard' (see app.tsx ternary). So when the
19
+ * wizard's internal step advanced to 'api_key', the user could SEE the
20
+ * "输入 API Key: 服务商: deepseek" prompt but had NO way to type into
21
+ * it. Ink silently swallowed keystrokes (no useInput handler was
22
+ * active), and the user was stuck on a frozen screen — exactly the
23
+ * bug that prompted the user-reported "选择 deepseek 然后退出":
24
+ * pressing Ctrl+C felt like the only escape.
25
+ *
26
+ * Fix: this file now uses `useInput` and `ink-text-input` for the text
27
+ * steps. The SetViewMode-based input delegation in app.tsx is no longer
28
+ * required for the InitWizard flow.
20
29
  */
21
30
  export declare function InitWizard({ onComplete, onCancel }: Props): React.JSX.Element | null;
22
31
  export type { InitStep };
@@ -1 +1 @@
1
- {"version":3,"file":"InitWizard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/InitWizard.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAA8B,MAAM,OAAO,CAAC;AAMnD,OAAO,EAAuC,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,UAAU,KAAK;IACb,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9F,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,KAAK,QAAQ,GACT,UAAU,GACV,SAAS,GACT,OAAO,GACP,cAAc,GACd,YAAY,GACZ,gBAAgB,GAChB,WAAW,CAAC;AAOhB;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,4BA4KzD;AAGD,YAAY,EAAE,QAAQ,EAAE,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"InitWizard.d.ts","sourceRoot":"","sources":["../../../src/tui/components/InitWizard.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAAmB,MAAM,OAAO,CAAC;AAOxC,OAAO,EAAuC,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,UAAU,KAAK;IACb,UAAU,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9F,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,KAAK,QAAQ,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAOlH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,UAAU,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,4BAwNzD;AAGD,YAAY,EAAE,QAAQ,EAAE,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,22 +1,32 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /** @jsxImportSource react */
3
3
  import { useState } from 'react';
4
- import { Box, Text } from 'ink';
4
+ import { Box, Text, useInput } from 'ink';
5
5
  import SelectInput from 'ink-select-input';
6
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
6
+ import TextInput from 'ink-text-input';
7
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
7
8
  import { join } from 'path';
8
9
  import { homedir } from 'os';
9
10
  import { listProviders, getModelsForProvider, isCustomProvider } from '../../config/providers.js';
10
11
  /**
11
- * v3.0.0: InitWizard gained two new steps after model selection:
12
- * - cache_strategy: enable / disable prompt caching
13
- * - cache_ttl: 5m vs 1h (only if enabled)
12
+ * v3.0.1: InitWizard is now fully self-contained it manages its own
13
+ * step state AND its own keyboard input for text-entry steps (api_key,
14
+ * custom_url, custom_model). The previous version had a fatal bug:
14
15
  *
15
- * The defaults mirror ConfigManager.DEFAULT_CONFIG (enabled, 5m). Users on
16
- * OpenAI / DeepSeek / Gemini can ignore these those providers do
17
- * automatic caching and the flag is purely advisory there. The flag
18
- * matters for Anthropic users who want to opt out of cache_control
19
- * markers or pick a longer TTL.
16
+ * The text-entry steps (`api_key`, `custom_url`, `custom_model`) only
17
+ * rendered a `<Text>` prompt with no actual input box. The host
18
+ * component (app.tsx) had its own UserInput BUT only rendered it when
19
+ * viewMode was NOT 'init_wizard' (see app.tsx ternary). So when the
20
+ * wizard's internal step advanced to 'api_key', the user could SEE the
21
+ * "输入 API Key: 服务商: deepseek" prompt but had NO way to type into
22
+ * it. Ink silently swallowed keystrokes (no useInput handler was
23
+ * active), and the user was stuck on a frozen screen — exactly the
24
+ * bug that prompted the user-reported "选择 deepseek 然后退出":
25
+ * pressing Ctrl+C felt like the only escape.
26
+ *
27
+ * Fix: this file now uses `useInput` and `ink-text-input` for the text
28
+ * steps. The SetViewMode-based input delegation in app.tsx is no longer
29
+ * required for the InitWizard flow.
20
30
  */
21
31
  export function InitWizard({ onComplete, onCancel }) {
22
32
  const [step, setStep] = useState('provider');
@@ -39,7 +49,6 @@ export function InitWizard({ onComplete, onCancel }) {
39
49
  temperature: 0.7,
40
50
  maxTokens: 4096,
41
51
  contextLength: 50,
42
- // v3.0.0: cache policy from wizard
43
52
  cache: {
44
53
  enabled: cacheChoice.enabled,
45
54
  ttl: cacheChoice.ttl,
@@ -49,26 +58,23 @@ export function InitWizard({ onComplete, onCancel }) {
49
58
  if (url)
50
59
  config.baseUrl = url;
51
60
  writeFileSync(configPath, JSON.stringify(config, null, 2));
52
- // Save to models history
53
- const historyPath = join(dir, 'models.json');
54
- let history = [];
55
- if (existsSync(historyPath)) {
56
- try {
57
- history = JSON.parse(readFileSync(historyPath, 'utf-8'));
58
- }
59
- catch { }
60
- }
61
- if (!history.includes(model)) {
62
- history.push(model);
63
- writeFileSync(historyPath, JSON.stringify(history, null, 2));
64
- }
65
61
  };
62
+ // v3.0.1: ESC cancels the wizard from any text-entry step. This is the
63
+ // hook that the previous version was missing — when the user pressed
64
+ // ESC on the frozen "输入 API Key" screen, nothing happened because no
65
+ // useInput was active. Now it bails out cleanly.
66
+ useInput((_input, key) => {
67
+ if (key.escape && (step === 'api_key' || step === 'custom_url' || step === 'custom_model')) {
68
+ onCancel();
69
+ }
70
+ });
66
71
  // Step 1: Provider selection
67
72
  if (step === 'provider') {
68
73
  const items = providers.map(p => ({ label: p.name, value: p.key }));
69
74
  return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u9009\u62E9\u670D\u52A1\u5546 (\u2191\u2193 \u56DE\u8F66):" }), _jsx(SelectInput, { items: items, onSelect: (item) => {
70
- setSelectedProvider(item.value);
71
- if (isCustomProvider(item.value)) {
75
+ const provider = item.value;
76
+ setSelectedProvider(provider);
77
+ if (isCustomProvider(provider)) {
72
78
  setStep('custom_url');
73
79
  }
74
80
  else {
@@ -76,13 +82,31 @@ export function InitWizard({ onComplete, onCancel }) {
76
82
  }
77
83
  } })] }));
78
84
  }
79
- // Custom URL input
85
+ // Custom URL input — v3.0.1 NOW has a real TextInput
80
86
  if (step === 'custom_url') {
81
- return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u4E2D\u8F6C\u7AD9 URL:" }), _jsx(Text, { dimColor: true, children: "\u4F8B\u5982: https://api.example.com/v1" }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165 URL \u5E76\u56DE\u8F66\uFF09" })] }));
87
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u4E2D\u8F6C\u7AD9 URL:" }), _jsx(Text, { dimColor: true, children: "\u4F8B\u5982: https://api.example.com/v1" }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165 URL \u5E76\u56DE\u8F66\uFF0CESC \u53D6\u6D88\uFF09" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "#06B6D4", children: "\u276F " }), _jsx(TextInput, { value: customUrl, onChange: setCustomUrl, onSubmit: (value) => {
88
+ if (value.trim()) {
89
+ setCustomUrl(value.trim());
90
+ setStep('api_key');
91
+ }
92
+ } })] })] }));
82
93
  }
83
- // Step 2: API Key
94
+ // Step 2: API Key — v3.0.1 NOW has a real TextInput
84
95
  if (step === 'api_key') {
85
- return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165 API Key:" }), _jsxs(Text, { dimColor: true, children: ["\u670D\u52A1\u5546: ", providers.find(p => p.key === selectedProvider)?.name] }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165 Key \u5E76\u56DE\u8F66\uFF09" })] }));
96
+ const providerLabel = providers.find(p => p.key === selectedProvider)?.name || selectedProvider;
97
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165 API Key:" }), _jsxs(Text, { dimColor: true, children: ["\u670D\u52A1\u5546: ", providerLabel] }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165 Key \u5E76\u56DE\u8F66\uFF0CESC \u53D6\u6D88\uFF09" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "#06B6D4", children: "\u276F " }), _jsx(TextInput, { value: apiKey, onChange: setApiKey, onSubmit: (value) => {
98
+ if (value.trim()) {
99
+ setApiKey(value.trim());
100
+ if (isCustomProvider(selectedProvider)) {
101
+ // Custom OpenAI/Anthropic: after key, go to model
102
+ setStep('model');
103
+ }
104
+ else {
105
+ // Standard providers: skip to model selection
106
+ setStep('model');
107
+ }
108
+ }
109
+ } })] })] }));
86
110
  }
87
111
  // Step 3: Model selection
88
112
  if (step === 'model') {
@@ -96,14 +120,18 @@ export function InitWizard({ onComplete, onCancel }) {
96
120
  }
97
121
  else {
98
122
  setSelectedModel(item.value);
99
- // v3.0.0: prompt the user for cache strategy after model.
100
123
  setStep('cache_strategy');
101
124
  }
102
125
  } })] }));
103
126
  }
104
- // Custom model name
127
+ // Custom model name input — v3.0.1 NOW has a real TextInput
105
128
  if (step === 'custom_model') {
106
- return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u6A21\u578B\u540D\u79F0:" }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165\u6A21\u578B\u540D\u5E76\u56DE\u8F66\uFF09" })] }));
129
+ return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsx(Text, { color: "#06B6D4", bold: true, children: "\u8F93\u5165\u6A21\u578B\u540D\u79F0:" }), _jsx(Text, { color: "#F59E0B", children: "\uFF08\u8BF7\u76F4\u63A5\u8F93\u5165\u6A21\u578B\u540D\u5E76\u56DE\u8F66\uFF0CESC \u53D6\u6D88\uFF09" }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "#06B6D4", children: "\u276F " }), _jsx(TextInput, { value: selectedModel, onChange: setSelectedModel, onSubmit: (value) => {
130
+ if (value.trim()) {
131
+ setSelectedModel(value.trim());
132
+ setStep('cache_strategy');
133
+ }
134
+ } })] })] }));
107
135
  }
108
136
  // v3.0.0: prompt-cache strategy step
109
137
  if (step === 'cache_strategy') {
@@ -1 +1 @@
1
- {"version":3,"file":"InitWizard.js","sourceRoot":"","sources":["../../../src/tui/components/InitWizard.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InitWizard.js","sourceRoot":"","sources":["../../../src/tui/components/InitWizard.tsx"],"names":[],"mappings":"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"}
@@ -1,10 +1,12 @@
1
1
  /** @jsxImportSource react */
2
2
  import React from 'react';
3
+ import type { ProviderName } from '../../config/types.js';
3
4
  interface Props {
4
5
  currentModel: string;
6
+ currentProvider?: ProviderName;
5
7
  onSelect: (model: string) => void;
6
8
  onAddNew: () => void;
7
9
  }
8
- export declare function ModelSelector({ currentModel, onSelect, onAddNew }: Props): React.JSX.Element;
10
+ export declare function ModelSelector({ currentModel, currentProvider, onSelect, onAddNew }: Props): React.JSX.Element;
9
11
  export {};
10
12
  //# sourceMappingURL=ModelSelector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../../src/tui/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAA8B,MAAM,OAAO,CAAC;AAOnD,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAgDD,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,qBA0BxE"}
1
+ {"version":3,"file":"ModelSelector.d.ts","sourceRoot":"","sources":["../../../src/tui/components/ModelSelector.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAA8B,MAAM,OAAO,CAAC;AAOnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,UAAU,KAAK;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAiED,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,qBA0BzF"}
@@ -6,11 +6,12 @@ import SelectInput from 'ink-select-input';
6
6
  import { readFileSync, existsSync } from 'fs';
7
7
  import { join } from 'path';
8
8
  import { homedir } from 'os';
9
- function loadSavedModels() {
9
+ import { PROVIDERS, getModelsForProvider } from '../../config/providers.js';
10
+ function loadSavedModels(currentProvider) {
10
11
  const configPath = join(homedir(), '.thatgfsj', 'config.json');
11
12
  const models = [];
12
13
  const seen = new Set();
13
- // Load from history if exists
14
+ // 1. Load from history if exists
14
15
  const historyPath = join(homedir(), '.thatgfsj', 'models.json');
15
16
  if (existsSync(historyPath)) {
16
17
  try {
@@ -24,7 +25,7 @@ function loadSavedModels() {
24
25
  }
25
26
  catch { }
26
27
  }
27
- // Always include current model
28
+ // 2. Always include current model
28
29
  if (existsSync(configPath)) {
29
30
  try {
30
31
  const config = JSON.parse(readFileSync(configPath, 'utf-8'));
@@ -35,7 +36,23 @@ function loadSavedModels() {
35
36
  }
36
37
  catch { }
37
38
  }
38
- // Add some common defaults if list is empty
39
+ // 3. v3.0.0 bug fix: ALWAYS include the current provider's catalog of
40
+ // models, otherwise users on a custom relay (mimo / one-api / etc.) who
41
+ // only have the current model in history see a list of 1 item and can't
42
+ // switch to deepseek / gpt-4o / etc. without going through init wizard.
43
+ // This is the model_selector "选 deepseek 然后退出" bug: the list only
44
+ // contained the current model, so the user pressed Enter on the wrong
45
+ // item (or thought the list was broken), then Ctrl+C'd out.
46
+ if (currentProvider && PROVIDERS[currentProvider]) {
47
+ const catalog = getModelsForProvider(currentProvider);
48
+ for (const m of catalog) {
49
+ if (!seen.has(m.id)) {
50
+ seen.add(m.id);
51
+ models.push({ label: m.id, value: m.id });
52
+ }
53
+ }
54
+ }
55
+ // 4. Universal fallbacks if user is on no history and no catalog
39
56
  if (models.length === 0) {
40
57
  const defaults = ['deepseek-chat', 'gpt-4o', 'mimo-v2.5-pro'];
41
58
  for (const m of defaults) {
@@ -44,14 +61,14 @@ function loadSavedModels() {
44
61
  }
45
62
  return models;
46
63
  }
47
- export function ModelSelector({ currentModel, onSelect, onAddNew }) {
64
+ export function ModelSelector({ currentModel, currentProvider, onSelect, onAddNew }) {
48
65
  const [items, setItems] = useState([]);
49
66
  useEffect(() => {
50
- const saved = loadSavedModels();
67
+ const saved = loadSavedModels(currentProvider);
51
68
  // Add "add new" option at the end
52
69
  saved.push({ label: '+ 添加新模型', value: '__add_new__' });
53
70
  setItems(saved);
54
- }, []);
71
+ }, [currentProvider]);
55
72
  return (_jsxs(Box, { flexDirection: "column", paddingLeft: 1, children: [_jsxs(Text, { color: "#06B6D4", bold: true, children: ["\u5F53\u524D\u6A21\u578B: ", currentModel] }), _jsx(Text, { dimColor: true, children: "\u9009\u62E9\u6A21\u578B (\u2191\u2193 \u56DE\u8F66):" }), _jsx(SelectInput, { items: items, onSelect: (item) => {
56
73
  if (item.value === '__add_new__') {
57
74
  onAddNew();
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.js","sourceRoot":"","sources":["../../../src/tui/components/ModelSelector.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ModelSelector.js","sourceRoot":"","sources":["../../../src/tui/components/ModelSelector.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"UserInput.d.ts","sourceRoot":"","sources":["../../../src/tui/components/UserInput.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,qBAuHhE"}
1
+ {"version":3,"file":"UserInput.d.ts","sourceRoot":"","sources":["../../../src/tui/components/UserInput.tsx"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,KAAK,qBA2IhE"}
@@ -37,6 +37,26 @@ export function UserInput({ onSubmit, onCancel, disabled }) {
37
37
  }
38
38
  if (key.tab || key.return) {
39
39
  const selected = filteredCommands[selectedCmd] || filteredCommands[0];
40
+ // v3.0.0 bug fix: previously we set `value = selected.name + ' '` and
41
+ // returned, which forced the user to press Enter a SECOND time to
42
+ // actually execute the command. For single-word commands like
43
+ // /模型 /新建 /压缩 /帮助 /技能 etc. that meant: "press Enter twice
44
+ // to switch model", which is confusing and a reproduce-and-exit
45
+ // vector if the user panics and Ctrl+C's in the middle.
46
+ //
47
+ // Fix: when Enter is pressed on a command-list item, EXECUTE the
48
+ // command directly. If the user wants to append args (e.g. /模型
49
+ // <name>), they can type them after the slash. Tab still writes
50
+ // the name into the input so the user can append text.
51
+ if (key.return) {
52
+ setSelectedCmd(0);
53
+ setValue('');
54
+ setHistory(prev => [...prev, selected.name]);
55
+ setHistoryIdx(-1);
56
+ onSubmit(selected.name);
57
+ return;
58
+ }
59
+ // Tab: write the name into the input so the user can append args.
40
60
  setValue(selected.name + ' ');
41
61
  setSelectedCmd(0);
42
62
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"UserInput.js","sourceRoot":"","sources":["../../../src/tui/components/UserInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UserInput.js","sourceRoot":"","sources":["../../../src/tui/components/UserInput.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thatgfsj-code",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Thatgfsj Code - AI Coding Assistant with Reasonix-style prompt caching",
5
5
  "main": "dist/cmd/index.js",
6
6
  "type": "module",
@@ -42,6 +42,7 @@
42
42
  "@types/marked-terminal": "^6.1.1",
43
43
  "@types/node": "^20.10.0",
44
44
  "@types/react": "^19.2.17",
45
+ "ink-testing-library": "^4.0.0",
45
46
  "typescript": "^5.3.0",
46
47
  "vitest": "^4.1.10"
47
48
  }
package/src/app/index.ts CHANGED
@@ -116,12 +116,21 @@ export class App {
116
116
  async *streamResponse(messages?: ChatMessage[]): AsyncGenerator<StreamChunk, ChatResponse> {
117
117
  const msgs = messages || this.session.getMessages();
118
118
  const inner = this.llm.chatStream(msgs);
119
+ const debugUsage = !!process.env.GFCODE_DEBUG_USAGE;
119
120
  let next = await inner.next();
120
121
  while (!next.done) {
121
122
  // Forward chunks unchanged, but capture usage into the persistent
122
123
  // cache stats store so the TUI Header / /cache command can read it.
123
124
  if (next.value && next.value.type === 'usage') {
124
125
  try { this.cacheStats.record(next.value.usage); } catch { /* best-effort */ }
126
+ if (debugUsage) {
127
+ // v3.0.0 DEBUG: dump raw usage fields to stderr so the user can
128
+ // confirm whether the upstream provider/relay forwards cache stats.
129
+ // Enable with: GFCODE_DEBUG_USAGE=1 gfcode ...
130
+ process.stderr.write(
131
+ '[debug_usage] ' + JSON.stringify(next.value.usage) + '\n'
132
+ );
133
+ }
125
134
  }
126
135
  yield next.value;
127
136
  next = await inner.next();
package/src/tui/app.tsx CHANGED
@@ -12,7 +12,6 @@ import { useChat } from './hooks/useChat.js';
12
12
  import { useCommands } from './hooks/useCommands.js';
13
13
  import type { App } from '../app/index.js';
14
14
  import type { MessageData } from './components/ChatMessage.js';
15
- import type { ProviderName } from '../config/types.js';
16
15
  import { writeFileSync, readFileSync, existsSync, mkdirSync } from 'fs';
17
16
  import { join } from 'path';
18
17
  import { homedir } from 'os';
@@ -35,15 +34,13 @@ function saveModelToHistory(model: string) {
35
34
  }
36
35
  }
37
36
 
38
- type ViewMode = 'chat' | 'model_select' | 'init_wizard' | 'init_key' | 'init_url' | 'init_custom_model';
37
+ type ViewMode = 'chat' | 'model_select' | 'init_wizard';
39
38
 
40
39
  export function TuiApp({ app }: Props) {
41
40
  const { messages, isThinking, streaming, streamingToolCalls, queuedMessage, sendMessage, cancel } = useChat(app);
42
41
  const { handleCommand } = useCommands(app);
43
42
  const [systemMessages, setSystemMessages] = useState<MessageData[]>([]);
44
43
  const [viewMode, setViewMode] = useState<ViewMode>('chat');
45
- const [initProvider, setInitProvider] = useState<ProviderName>('siliconflow');
46
- const [initUrl, setInitUrl] = useState('');
47
44
  const { stdout } = useStdout();
48
45
  const terminalWidth = stdout?.columns || 80;
49
46
 
@@ -60,41 +57,6 @@ export function TuiApp({ app }: Props) {
60
57
  }, []);
61
58
 
62
59
  const onSubmit = useCallback(async (input: string) => {
63
- // Init wizard - API Key input
64
- if (viewMode === 'init_key') {
65
- const key = input.trim();
66
- if (!key) { setViewMode('chat'); return; }
67
- // Save and complete
68
- const { App: AppClass } = await import('../app/index.js');
69
- const cfg = app.config.get();
70
- app.config.save({ provider: initProvider, apiKey: key, model: cfg.model || 'default' });
71
- saveModelToHistory(cfg.model || 'default');
72
- setViewMode('chat');
73
- addMsg(`配置已更新: ${initProvider}`);
74
- return;
75
- }
76
-
77
- // Init wizard - Custom URL input
78
- if (viewMode === 'init_url') {
79
- const url = input.trim();
80
- if (!url) { setViewMode('chat'); return; }
81
- setInitUrl(url);
82
- setViewMode('init_key');
83
- return;
84
- }
85
-
86
- // Init wizard - Custom model name
87
- if (viewMode === 'init_custom_model') {
88
- const model = input.trim();
89
- if (model) {
90
- app.config.save({ model });
91
- saveModelToHistory(model);
92
- addMsg(`模型已切换: ${model}`);
93
- }
94
- setViewMode('chat');
95
- return;
96
- }
97
-
98
60
  // Model selector - ignore text input
99
61
  if (viewMode === 'model_select') return;
100
62
 
@@ -125,7 +87,7 @@ export function TuiApp({ app }: Props) {
125
87
  }
126
88
 
127
89
  sendMessage(input);
128
- }, [handleCommand, sendMessage, app, viewMode, initProvider, initUrl, addMsg]);
90
+ }, [handleCommand, sendMessage, app, viewMode, addMsg]);
129
91
 
130
92
  const allMessages = [...systemMessages, ...messages];
131
93
  const activeSkills = app.skills.listActive().map(s => s.id);
@@ -154,6 +116,7 @@ export function TuiApp({ app }: Props) {
154
116
  {viewMode === 'model_select' ? (
155
117
  <ModelSelector
156
118
  currentModel={app.config.get().model}
119
+ currentProvider={app.config.get().provider}
157
120
  onSelect={(model) => {
158
121
  app.config.save({ model });
159
122
  saveModelToHistory(model);
@@ -163,6 +126,12 @@ export function TuiApp({ app }: Props) {
163
126
  onAddNew={() => setViewMode('init_wizard')}
164
127
  />
165
128
  ) : viewMode === 'init_wizard' ? (
129
+ // v3.0.1: InitWizard is now fully self-contained — it owns its own
130
+ // input handling via useInput + ink-text-input. No external UserInput
131
+ // is rendered here, and app.tsx no longer has the text-entry
132
+ // viewModes (init_key / init_url / init_custom_model) because they
133
+ // were the broken input-handling path that left users stuck on a
134
+ // frozen "输入 API Key" screen with no way to type.
166
135
  <InitWizard
167
136
  onComplete={(provider, model, apiKey, baseUrl) => {
168
137
  app.config.save({ provider, model, apiKey, baseUrl });
@@ -174,22 +143,6 @@ export function TuiApp({ app }: Props) {
174
143
  />
175
144
  ) : (
176
145
  <Box flexDirection="column">
177
- {viewMode === 'init_key' && (
178
- <Box paddingLeft={1} marginBottom={0}>
179
- <Text color="#06B6D4" bold>输入 API Key: </Text>
180
- <Text dimColor>({initProvider})</Text>
181
- </Box>
182
- )}
183
- {viewMode === 'init_url' && (
184
- <Box paddingLeft={1} marginBottom={0}>
185
- <Text color="#06B6D4" bold>输入中转站 URL: </Text>
186
- </Box>
187
- )}
188
- {viewMode === 'init_custom_model' && (
189
- <Box paddingLeft={1} marginBottom={0}>
190
- <Text color="#06B6D4" bold>输入模型名称: </Text>
191
- </Box>
192
- )}
193
146
  <UserInput onSubmit={onSubmit} onCancel={cancel} disabled={false} />
194
147
  </Box>
195
148
  )}
@@ -1,8 +1,9 @@
1
1
  /** @jsxImportSource react */
2
- import React, { useState, useEffect } from 'react';
3
- import { Box, Text } from 'ink';
2
+ import React, { useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
4
  import SelectInput from 'ink-select-input';
5
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
5
+ import TextInput from 'ink-text-input';
6
+ import { writeFileSync, existsSync, mkdirSync } from 'fs';
6
7
  import { join } from 'path';
7
8
  import { homedir } from 'os';
8
9
  import { listProviders, getModelsForProvider, isCustomProvider } from '../../config/providers.js';
@@ -13,14 +14,7 @@ interface Props {
13
14
  onCancel: () => void;
14
15
  }
15
16
 
16
- type InitStep =
17
- | 'provider'
18
- | 'api_key'
19
- | 'model'
20
- | 'custom_model'
21
- | 'custom_url'
22
- | 'cache_strategy'
23
- | 'cache_ttl';
17
+ type InitStep = 'provider' | 'custom_url' | 'api_key' | 'model' | 'custom_model' | 'cache_strategy' | 'cache_ttl';
24
18
 
25
19
  interface CacheChoice {
26
20
  enabled: boolean;
@@ -28,15 +22,24 @@ interface CacheChoice {
28
22
  }
29
23
 
30
24
  /**
31
- * v3.0.0: InitWizard gained two new steps after model selection:
32
- * - cache_strategy: enable / disable prompt caching
33
- * - cache_ttl: 5m vs 1h (only if enabled)
25
+ * v3.0.1: InitWizard is now fully self-contained it manages its own
26
+ * step state AND its own keyboard input for text-entry steps (api_key,
27
+ * custom_url, custom_model). The previous version had a fatal bug:
34
28
  *
35
- * The defaults mirror ConfigManager.DEFAULT_CONFIG (enabled, 5m). Users on
36
- * OpenAI / DeepSeek / Gemini can ignore these those providers do
37
- * automatic caching and the flag is purely advisory there. The flag
38
- * matters for Anthropic users who want to opt out of cache_control
39
- * markers or pick a longer TTL.
29
+ * The text-entry steps (`api_key`, `custom_url`, `custom_model`) only
30
+ * rendered a `<Text>` prompt with no actual input box. The host
31
+ * component (app.tsx) had its own UserInput BUT only rendered it when
32
+ * viewMode was NOT 'init_wizard' (see app.tsx ternary). So when the
33
+ * wizard's internal step advanced to 'api_key', the user could SEE the
34
+ * "输入 API Key: 服务商: deepseek" prompt but had NO way to type into
35
+ * it. Ink silently swallowed keystrokes (no useInput handler was
36
+ * active), and the user was stuck on a frozen screen — exactly the
37
+ * bug that prompted the user-reported "选择 deepseek 然后退出":
38
+ * pressing Ctrl+C felt like the only escape.
39
+ *
40
+ * Fix: this file now uses `useInput` and `ink-text-input` for the text
41
+ * steps. The SetViewMode-based input delegation in app.tsx is no longer
42
+ * required for the InitWizard flow.
40
43
  */
41
44
  export function InitWizard({ onComplete, onCancel }: Props) {
42
45
  const [step, setStep] = useState<InitStep>('provider');
@@ -61,7 +64,6 @@ export function InitWizard({ onComplete, onCancel }: Props) {
61
64
  temperature: 0.7,
62
65
  maxTokens: 4096,
63
66
  contextLength: 50,
64
- // v3.0.0: cache policy from wizard
65
67
  cache: {
66
68
  enabled: cacheChoice.enabled,
67
69
  ttl: cacheChoice.ttl,
@@ -70,18 +72,17 @@ export function InitWizard({ onComplete, onCancel }: Props) {
70
72
  };
71
73
  if (url) config.baseUrl = url;
72
74
  writeFileSync(configPath, JSON.stringify(config, null, 2));
75
+ };
73
76
 
74
- // Save to models history
75
- const historyPath = join(dir, 'models.json');
76
- let history: string[] = [];
77
- if (existsSync(historyPath)) {
78
- try { history = JSON.parse(readFileSync(historyPath, 'utf-8')); } catch {}
77
+ // v3.0.1: ESC cancels the wizard from any text-entry step. This is the
78
+ // hook that the previous version was missing — when the user pressed
79
+ // ESC on the frozen "输入 API Key" screen, nothing happened because no
80
+ // useInput was active. Now it bails out cleanly.
81
+ useInput((_input, key) => {
82
+ if (key.escape && (step === 'api_key' || step === 'custom_url' || step === 'custom_model')) {
83
+ onCancel();
79
84
  }
80
- if (!history.includes(model)) {
81
- history.push(model);
82
- writeFileSync(historyPath, JSON.stringify(history, null, 2));
83
- }
84
- };
85
+ });
85
86
 
86
87
  // Step 1: Provider selection
87
88
  if (step === 'provider') {
@@ -92,8 +93,9 @@ export function InitWizard({ onComplete, onCancel }: Props) {
92
93
  <SelectInput
93
94
  items={items}
94
95
  onSelect={(item) => {
95
- setSelectedProvider(item.value as ProviderName);
96
- if (isCustomProvider(item.value as ProviderName)) {
96
+ const provider = item.value as ProviderName;
97
+ setSelectedProvider(provider);
98
+ if (isCustomProvider(provider)) {
97
99
  setStep('custom_url');
98
100
  } else {
99
101
  setStep('api_key');
@@ -104,24 +106,57 @@ export function InitWizard({ onComplete, onCancel }: Props) {
104
106
  );
105
107
  }
106
108
 
107
- // Custom URL input
109
+ // Custom URL input — v3.0.1 NOW has a real TextInput
108
110
  if (step === 'custom_url') {
109
111
  return (
110
112
  <Box flexDirection="column" paddingLeft={1}>
111
113
  <Text color="#06B6D4" bold>输入中转站 URL:</Text>
112
114
  <Text dimColor>例如: https://api.example.com/v1</Text>
113
- <Text color="#F59E0B">(请直接输入 URL 并回车)</Text>
115
+ <Text color="#F59E0B">(请直接输入 URL 并回车,ESC 取消)</Text>
116
+ <Box marginTop={1}>
117
+ <Text color="#06B6D4">❯ </Text>
118
+ <TextInput
119
+ value={customUrl}
120
+ onChange={setCustomUrl}
121
+ onSubmit={(value) => {
122
+ if (value.trim()) {
123
+ setCustomUrl(value.trim());
124
+ setStep('api_key');
125
+ }
126
+ }}
127
+ />
128
+ </Box>
114
129
  </Box>
115
130
  );
116
131
  }
117
132
 
118
- // Step 2: API Key
133
+ // Step 2: API Key — v3.0.1 NOW has a real TextInput
119
134
  if (step === 'api_key') {
135
+ const providerLabel = providers.find(p => p.key === selectedProvider)?.name || selectedProvider;
120
136
  return (
121
137
  <Box flexDirection="column" paddingLeft={1}>
122
138
  <Text color="#06B6D4" bold>输入 API Key:</Text>
123
- <Text dimColor>服务商: {providers.find(p => p.key === selectedProvider)?.name}</Text>
124
- <Text color="#F59E0B">(请直接输入 Key 并回车)</Text>
139
+ <Text dimColor>服务商: {providerLabel}</Text>
140
+ <Text color="#F59E0B">(请直接输入 Key 并回车,ESC 取消)</Text>
141
+ <Box marginTop={1}>
142
+ <Text color="#06B6D4">❯ </Text>
143
+ <TextInput
144
+ value={apiKey}
145
+ onChange={setApiKey}
146
+ onSubmit={(value) => {
147
+ if (value.trim()) {
148
+ setApiKey(value.trim());
149
+ if (isCustomProvider(selectedProvider)) {
150
+ // Custom OpenAI/Anthropic: after key, go to model
151
+ setStep('model');
152
+ } else {
153
+ // Standard providers: skip to model selection
154
+ setStep('model');
155
+ }
156
+ }
157
+ }}
158
+ />
159
+ </Box>
125
160
  </Box>
126
161
  );
127
162
  }
@@ -142,7 +177,6 @@ export function InitWizard({ onComplete, onCancel }: Props) {
142
177
  setStep('custom_model');
143
178
  } else {
144
179
  setSelectedModel(item.value);
145
- // v3.0.0: prompt the user for cache strategy after model.
146
180
  setStep('cache_strategy');
147
181
  }
148
182
  }}
@@ -151,12 +185,25 @@ export function InitWizard({ onComplete, onCancel }: Props) {
151
185
  );
152
186
  }
153
187
 
154
- // Custom model name
188
+ // Custom model name input — v3.0.1 NOW has a real TextInput
155
189
  if (step === 'custom_model') {
156
190
  return (
157
191
  <Box flexDirection="column" paddingLeft={1}>
158
192
  <Text color="#06B6D4" bold>输入模型名称:</Text>
159
- <Text color="#F59E0B">(请直接输入模型名并回车)</Text>
193
+ <Text color="#F59E0B">(请直接输入模型名并回车,ESC 取消)</Text>
194
+ <Box marginTop={1}>
195
+ <Text color="#06B6D4">❯ </Text>
196
+ <TextInput
197
+ value={selectedModel}
198
+ onChange={setSelectedModel}
199
+ onSubmit={(value) => {
200
+ if (value.trim()) {
201
+ setSelectedModel(value.trim());
202
+ setStep('cache_strategy');
203
+ }
204
+ }}
205
+ />
206
+ </Box>
160
207
  </Box>
161
208
  );
162
209
  }
@@ -5,9 +5,12 @@ import SelectInput from 'ink-select-input';
5
5
  import { readFileSync, existsSync } from 'fs';
6
6
  import { join } from 'path';
7
7
  import { homedir } from 'os';
8
+ import { PROVIDERS, getModelsForProvider } from '../../config/providers.js';
9
+ import type { ProviderName } from '../../config/types.js';
8
10
 
9
11
  interface Props {
10
12
  currentModel: string;
13
+ currentProvider?: ProviderName;
11
14
  onSelect: (model: string) => void;
12
15
  onAddNew: () => void;
13
16
  }
@@ -17,12 +20,12 @@ interface SavedModel {
17
20
  value: string;
18
21
  }
19
22
 
20
- function loadSavedModels(): SavedModel[] {
23
+ function loadSavedModels(currentProvider?: ProviderName): SavedModel[] {
21
24
  const configPath = join(homedir(), '.thatgfsj', 'config.json');
22
25
  const models: SavedModel[] = [];
23
26
  const seen = new Set<string>();
24
27
 
25
- // Load from history if exists
28
+ // 1. Load from history if exists
26
29
  const historyPath = join(homedir(), '.thatgfsj', 'models.json');
27
30
  if (existsSync(historyPath)) {
28
31
  try {
@@ -36,7 +39,7 @@ function loadSavedModels(): SavedModel[] {
36
39
  } catch {}
37
40
  }
38
41
 
39
- // Always include current model
42
+ // 2. Always include current model
40
43
  if (existsSync(configPath)) {
41
44
  try {
42
45
  const config = JSON.parse(readFileSync(configPath, 'utf-8'));
@@ -47,7 +50,24 @@ function loadSavedModels(): SavedModel[] {
47
50
  } catch {}
48
51
  }
49
52
 
50
- // Add some common defaults if list is empty
53
+ // 3. v3.0.0 bug fix: ALWAYS include the current provider's catalog of
54
+ // models, otherwise users on a custom relay (mimo / one-api / etc.) who
55
+ // only have the current model in history see a list of 1 item and can't
56
+ // switch to deepseek / gpt-4o / etc. without going through init wizard.
57
+ // This is the model_selector "选 deepseek 然后退出" bug: the list only
58
+ // contained the current model, so the user pressed Enter on the wrong
59
+ // item (or thought the list was broken), then Ctrl+C'd out.
60
+ if (currentProvider && PROVIDERS[currentProvider]) {
61
+ const catalog = getModelsForProvider(currentProvider);
62
+ for (const m of catalog) {
63
+ if (!seen.has(m.id)) {
64
+ seen.add(m.id);
65
+ models.push({ label: m.id, value: m.id });
66
+ }
67
+ }
68
+ }
69
+
70
+ // 4. Universal fallbacks if user is on no history and no catalog
51
71
  if (models.length === 0) {
52
72
  const defaults = ['deepseek-chat', 'gpt-4o', 'mimo-v2.5-pro'];
53
73
  for (const m of defaults) {
@@ -58,15 +78,15 @@ function loadSavedModels(): SavedModel[] {
58
78
  return models;
59
79
  }
60
80
 
61
- export function ModelSelector({ currentModel, onSelect, onAddNew }: Props) {
81
+ export function ModelSelector({ currentModel, currentProvider, onSelect, onAddNew }: Props) {
62
82
  const [items, setItems] = useState<SavedModel[]>([]);
63
83
 
64
84
  useEffect(() => {
65
- const saved = loadSavedModels();
85
+ const saved = loadSavedModels(currentProvider);
66
86
  // Add "add new" option at the end
67
87
  saved.push({ label: '+ 添加新模型', value: '__add_new__' });
68
88
  setItems(saved);
69
- }, []);
89
+ }, [currentProvider]);
70
90
 
71
91
  return (
72
92
  <Box flexDirection="column" paddingLeft={1}>
@@ -46,6 +46,26 @@ export function UserInput({ onSubmit, onCancel, disabled }: Props) {
46
46
  }
47
47
  if (key.tab || key.return) {
48
48
  const selected = filteredCommands[selectedCmd] || filteredCommands[0];
49
+ // v3.0.0 bug fix: previously we set `value = selected.name + ' '` and
50
+ // returned, which forced the user to press Enter a SECOND time to
51
+ // actually execute the command. For single-word commands like
52
+ // /模型 /新建 /压缩 /帮助 /技能 etc. that meant: "press Enter twice
53
+ // to switch model", which is confusing and a reproduce-and-exit
54
+ // vector if the user panics and Ctrl+C's in the middle.
55
+ //
56
+ // Fix: when Enter is pressed on a command-list item, EXECUTE the
57
+ // command directly. If the user wants to append args (e.g. /模型
58
+ // <name>), they can type them after the slash. Tab still writes
59
+ // the name into the input so the user can append text.
60
+ if (key.return) {
61
+ setSelectedCmd(0);
62
+ setValue('');
63
+ setHistory(prev => [...prev, selected.name]);
64
+ setHistoryIdx(-1);
65
+ onSubmit(selected.name);
66
+ return;
67
+ }
68
+ // Tab: write the name into the input so the user can append args.
49
69
  setValue(selected.name + ' ');
50
70
  setSelectedCmd(0);
51
71
  return;
@@ -0,0 +1,31 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getModelsForProvider, PROVIDERS } from '../../src/config/providers.js';
3
+
4
+ describe('ModelSelector catalog integration', () => {
5
+ it('deepseek provider has deepseek-chat and deepseek-reasoner', () => {
6
+ const models = getModelsForProvider('deepseek');
7
+ const ids = models.map(m => m.id);
8
+ expect(ids).toContain('deepseek-chat');
9
+ expect(ids).toContain('deepseek-reasoner');
10
+ });
11
+
12
+ it('siliconflow provider has Qwen models', () => {
13
+ const models = getModelsForProvider('siliconflow');
14
+ const ids = models.map(m => m.id);
15
+ expect(ids).toContain('Qwen/Qwen2.5-7B-Instruct');
16
+ });
17
+
18
+ it('custom_openai provider has gpt-4o fallback', () => {
19
+ const models = getModelsForProvider('custom_openai');
20
+ const ids = models.map(m => m.id);
21
+ expect(ids).toContain('gpt-4o');
22
+ });
23
+
24
+ it('all known providers have a non-empty catalog', () => {
25
+ const knownProviders = Object.keys(PROVIDERS);
26
+ for (const p of knownProviders) {
27
+ const models = getModelsForProvider(p as any);
28
+ expect(models.length, `provider ${p} should have at least one model`).toBeGreaterThan(0);
29
+ }
30
+ });
31
+ });