Skip to content

Commit df7a4ed

Browse files
authored
Merge branch 'main' into feat/agent-setup-review
2 parents a592350 + 11251ab commit df7a4ed

3 files changed

Lines changed: 75 additions & 15 deletions

File tree

.github/workflows/ai-pr-review.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ jobs:
7676
- name: Run Claude Code review
7777
uses: anthropics/claude-code-action@v1.0.102
7878
env:
79-
ANTHROPIC_BASE_URL: https://api.minimax.io/anthropic
79+
ANTHROPIC_BASE_URL: https://api.minimaxi.com/anthropic
8080
PR_NUMBER: ${{ github.event.pull_request.number }}
8181
PR_TITLE: ${{ github.event.pull_request.title }}
8282
PR_URL: ${{ github.event.pull_request.html_url }}
@@ -90,7 +90,7 @@ jobs:
9090
github_token: ${{ secrets.GITHUB_TOKEN }}
9191
use_sticky_comment: true
9292
claude_args: |
93-
--model MiniMax-M2.7-highspeed
93+
--model MiniMax-M3
9494
--max-turns 300
9595
--allowed-tools Read,Glob,Grep
9696
prompt: |

src/output/quota-table.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ function formatDuration(ms: number, nowLabel: string): string {
5353
return hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
5454
}
5555

56+
// Compact tag for the quota window length shown next to the reset countdown,
57+
// e.g. a 5-hour rolling window ⇒ "5h", a daily window ⇒ "1d", weekly ⇒ "1w".
58+
function formatWindow(ms: number): string {
59+
const WEEK = 7 * 24 * 3600000;
60+
const DAY = 24 * 3600000;
61+
const HOUR = 3600000;
62+
if (ms <= 0) return '';
63+
if (ms % WEEK === 0) return `${ms / WEEK}w`;
64+
if (ms % DAY === 0) return `${ms / DAY}d`;
65+
if (ms >= HOUR) return `${Math.round(ms / HOUR)}h`;
66+
return `${Math.max(1, Math.round(ms / 60000))}m`;
67+
}
68+
5669
function formatDate(epochMs: number): string {
5770
return new Date(epochMs).toISOString().slice(0, 10);
5871
}
@@ -173,8 +186,15 @@ function renderUnavailableMetric(label: string, unavailableLabel: string, color:
173186
return `${label} [${'.'.repeat(COMPACT_BAR_WIDTH)}] ${unavailableLabel}`;
174187
}
175188

176-
function boxLine(w: number, l: string, f: string, r: string, c: boolean): string {
177-
return c ? `${D}${l}${f.repeat(w)}${r}${R}` : `+${'-'.repeat(w)}+`;
189+
// `div` is a 1-based offset (in display cells) of an optional column divider,
190+
// so the reset column can be boxed off: ├────┬────┤ / ├────┼────┤ / ╰────┴────╯.
191+
function boxLine(w: number, l: string, f: string, r: string, c: boolean, div?: number, divChar?: string): string {
192+
if (div === undefined || divChar === undefined) {
193+
return c ? `${D}${l}${f.repeat(w)}${r}${R}` : `+${'-'.repeat(w)}+`;
194+
}
195+
return c
196+
? `${D}${l}${f.repeat(div - 1)}${divChar}${f.repeat(w - div)}${r}${R}`
197+
: `+${'-'.repeat(div - 1)}+${'-'.repeat(w - div)}+`;
178198
}
179199

180200
function boxRow(content: string, innerW: number, visLen: number, color: boolean): string {
@@ -210,17 +230,29 @@ export function renderQuotaTable(models: QuotaModelRemain[], config: Config): vo
210230
isUnweekly(m.current_weekly_status),
211231
config.region === 'cn' ? UNLIMITED_LABEL_CN : UNLIMITED_LABEL_EN,
212232
);
213-
const reset = unavailable
214-
? `${L.resetsIn} —`
215-
: `${L.resetsIn} ${formatDuration(m.remains_time, L.now)}`;
233+
// The reset countdown lives in its own boxed column; the dim window tag
234+
// ("5h", "1w", …) tells which quota window the countdown applies to.
235+
const windowTag = unavailable ? '' : formatWindow(m.end_time - m.start_time);
236+
const resetLabel = windowTag ? `${windowTag} ${L.resetsIn}` : L.resetsIn;
237+
const resetValue = unavailable ? '—' : formatDuration(m.remains_time, L.now);
238+
const reset = useColor ? `${D}${resetLabel}${R} ${resetValue}` : `${resetLabel} ${resetValue}`;
216239
return { displayName, current, weekly, reset };
217240
});
218241

219242
const nameWidth = Math.max(6, ...rows.map(r => displayWidth(r.displayName)));
220243
const currentWidth = Math.max(...rows.map(r => displayWidth(r.current)), 18);
221244
const weeklyWidth = Math.max(...rows.map(r => displayWidth(r.weekly)), 18);
222245
const resetWidth = Math.max(...rows.map(r => displayWidth(r.reset)), 10);
223-
const W = Math.max(72, nameWidth + 2 + currentWidth + 2 + weeklyWidth + 2 + resetWidth + 4);
246+
// Left section holds name + current + weekly; the reset column sits to the
247+
// right of the divider. Keep the historical 72-cell minimum by widening the
248+
// left section when the natural width falls short.
249+
let leftWidth = nameWidth + 2 + currentWidth + 2 + weeklyWidth;
250+
let W = leftWidth + 3 + resetWidth + 2;
251+
if (W < 72) {
252+
leftWidth += 72 - W;
253+
W = 72;
254+
}
255+
const divOffset = leftWidth + 3;
224256

225257
const weekRange = models.length > 0
226258
? `${formatDate(models[0]!.weekly_start_time)}${formatDate(models[0]!.weekly_end_time)}`
@@ -244,17 +276,18 @@ export function renderQuotaTable(models: QuotaModelRemain[], config: Config): vo
244276
return;
245277
}
246278

247-
for (const row of rows) {
248-
console.log(boxLine(W, '├', '─', '┤', useColor));
279+
rows.forEach((row, i) => {
280+
console.log(boxLine(W, '├', '─', '┤', useColor, divOffset, i === 0 ? '┬' : '┼'));
249281

250282
const name = useColor ? `${B}${row.displayName}${R}` : row.displayName;
251-
const line = `${name}${' '.repeat(Math.max(1, nameWidth - displayWidth(row.displayName) + 2))}` +
283+
const left = `${name}${' '.repeat(Math.max(1, nameWidth - displayWidth(row.displayName) + 2))}` +
252284
`${row.current}${' '.repeat(Math.max(1, currentWidth - displayWidth(row.current) + 2))}` +
253-
`${row.weekly}${' '.repeat(Math.max(1, weeklyWidth - displayWidth(row.weekly) + 2))}` +
254-
row.reset;
285+
row.weekly;
286+
const divider = useColor ? `${D}${R}` : '|';
287+
const line = `${left}${' '.repeat(Math.max(0, leftWidth - displayWidth(left)))} ${divider} ${row.reset}`;
255288
console.log(boxRow(line, W, displayWidth(line), useColor));
256-
}
289+
});
257290

258-
console.log(boxLine(W, '╰', '─', '╯', useColor));
291+
console.log(boxLine(W, '╰', '─', '╯', useColor, divOffset, '┴'));
259292
console.log('');
260293
}

test/output/quota-table.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,33 @@ describe('renderQuotaTable', () => {
130130
expect(output).not.toContain('0 / 3');
131131
});
132132

133+
it('renders the reset countdown in a boxed column with the window duration tag', () => {
134+
const lines: string[] = [];
135+
const originalLog = console.log;
136+
137+
console.log = (message?: unknown) => {
138+
lines.push(String(message ?? ''));
139+
};
140+
141+
try {
142+
renderQuotaTable(createCodingPlanModels(), { ...createConfig(), noColor: true });
143+
} finally {
144+
console.log = originalLog;
145+
}
146+
147+
const output = lines.join('\n');
148+
149+
// general: 2-hour rolling window; video: daily window.
150+
expect(output).toContain('| 2h Reset 2h 0m |');
151+
expect(output).toContain('| 1d Reset 6h 0m |');
152+
// Every data row carries the column divider before the reset cell.
153+
const dataRows = lines.filter(l => l.includes('Reset'));
154+
expect(dataRows.length).toBe(2);
155+
for (const row of dataRows) {
156+
expect(row.split('|').length).toBe(4);
157+
}
158+
});
159+
133160
it('applies weekly_boost_permille (1500 ⇒ up to 150%) when rendering weekly percent', () => {
134161
const lines: string[] = [];
135162
const originalLog = console.log;

0 commit comments

Comments
 (0)