Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/stop-cron-after-close.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pymodel/pythinker-code": patch
---

Prevent cron ticks from continuing after an agent shuts down.
5 changes: 5 additions & 0 deletions .changeset/use-unicode-ellipsis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pymodel/pythinker-code": patch
---

Use the Unicode ellipsis in terminal status and truncation text.
2 changes: 1 addition & 1 deletion apps/pythinker-code/src/tui/commands/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ async function installFromPanel(
if (official) {
panel.setInstalling(truncateForStatus(label));
} else {
host.showStatus(`Installing or updating ${label} from marketplace...`);
host.showStatus(`Installing or updating ${label} from marketplace`);
}
host.state.ui.requestRender();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export class CompactionComponent extends Container {
return `${bullet}${label}`;
}
const bullet = this.blinkOn ? currentTheme.fg('text', STATUS_BULLET) : ' ';
const label = currentTheme.boldFg('primary', 'Compacting context...');
const label = currentTheme.boldFg('primary', 'Compacting context');
const tip = this.tip ? currentTheme.fg('textDim', ` · Tip: ${this.tip}`) : '';
return `${bullet}${label}${tip}`;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ export class QuestionDialogComponent extends Container implements Focusable {
appendWrapped(lines, ' ', ' ', bodyLine, renderWidth, dim);
}
if (bodyLines.length > visibleBodyLines.length) {
lines.push(dim(` ... ${String(bodyLines.length - visibleBodyLines.length)} more lines`));
lines.push(dim(` ${String(bodyLines.length - visibleBodyLines.length)} more lines`));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ export class SessionPickerComponent extends Container implements Focusable {
if (this.loading) {
lines.push(currentTheme.boldFg('primary', truncateToWidth(title, width, ELLIPSIS)));
lines.push(
currentTheme.fg('textMuted', truncateToWidth('Loading sessions...', width, ELLIPSIS)),
currentTheme.fg('textMuted', truncateToWidth('Loading sessions', width, ELLIPSIS)),
);
lines.push(currentTheme.fg('primary', '─'.repeat(width)));
return lines;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ const AGENT_DYNAMIC_WORKFLOW_LEFT_INDENT = ' ';
const AGENT_DYNAMIC_WORKFLOW_RIGHT_GAP = 1;
const AGENT_DYNAMIC_WORKFLOW_NON_GRID_LINES = 6;
const COMPACT_TERMINAL_MARK_WIDTH = 1;
const ORCHESTRATING_LABEL = 'Orchestrating...';
const PROMPTING_LABEL = 'Prompting...';
const WORKING_LABEL = 'Working...';
const ORCHESTRATING_LABEL = 'Orchestrating';
const PROMPTING_LABEL = 'Prompting';
const WORKING_LABEL = 'Working';
const COMPLETED_LABEL = 'Completed.';
const FAILED_LABEL = 'Failed.';
const ABORTED_LABEL = 'Aborted.';
const CANCELLED_LABEL = 'Cancelled.';
const QUEUED_LABEL = 'Queued...';
const SUSPENDED_LABEL = 'Rate limited...';
const QUEUED_LABEL = 'Queued';
const SUSPENDED_LABEL = 'Rate limited';
const RESUMED_ITEM_LABEL = '(resumed)';
const CANCELLED_LABEL_DARKEN_FACTOR = 0.72;
const AGENT_ID_TOKENS = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const TIMER_INTERVAL_MS = 1000;
const MAX_COMBINED_CHARS = 256 * 1024;
const KEEP_COMBINED_CHARS = 64 * 1024;

const TRUNCATED_RUNNING_NOTICE = '... (output truncated)';
const TRUNCATED_RUNNING_NOTICE = ' (output truncated)';

/**
* Live view for a user-initiated `!` shell command. Two phases:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export class ThinkingComponent implements Component {
rendered = [];
} else {
const contentLines = this.renderContent(width);
const hint = `... (${String(contentLines.length)} more lines, ctrl+o to expand)`;
const hint = ` (${String(contentLines.length)} more lines, ctrl+o to expand)`;
const prefix = this.showMarker ? currentTheme.fg('textDim', STATUS_BULLET) : MESSAGE_INDENT;
const styledHint = currentTheme.fg(
'textDim',
Expand Down
12 changes: 6 additions & 6 deletions apps/pythinker-code/src/tui/components/messages/tool-call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ function truncateArgValue(key: string, value: string): string {
// still tell which file is being touched.
return '…' + value.slice(value.length - (MAX_ARG_LENGTH - 1));
}
return value.slice(0, MAX_ARG_LENGTH - 3) + '...';
return value.slice(0, MAX_ARG_LENGTH - 1) + '';
}

function makeWorkspaceRelativePath(filePath: string, workspaceDir: string | undefined): string {
Expand Down Expand Up @@ -813,7 +813,7 @@ export class ToolCallComponent extends Container {
if (this.result !== undefined || text.length === 0) return;
this.liveOutput += text;
if (this.liveOutput.length > MAX_LIVE_OUTPUT_CHARS) {
this.liveOutput = `[...truncated]\n${this.liveOutput.slice(
this.liveOutput = `[truncated]\n${this.liveOutput.slice(
this.liveOutput.length - MAX_LIVE_OUTPUT_CHARS,
)}`;
}
Expand Down Expand Up @@ -1422,7 +1422,7 @@ export class ToolCallComponent extends Container {
const existingOutput = options?.replace === true ? '' : (activity?.output ?? '');
let output = existingOutput + text;
if (output.length > MAX_LIVE_OUTPUT_CHARS) {
output = `[...truncated]\n${output.slice(output.length - MAX_LIVE_OUTPUT_CHARS)}`;
output = `[truncated]\n${output.slice(output.length - MAX_LIVE_OUTPUT_CHARS)}`;
}
this.upsertSubToolActivity(id, name, args, activity?.phase ?? 'ongoing', output);
this.rebuildContent();
Expand Down Expand Up @@ -1673,7 +1673,7 @@ export class ToolCallComponent extends Container {
const suffix = this.hiddenSubCallCount > 1 ? 's' : '';
this.addChild(
new Text(
currentTheme.italic(currentTheme.dim(` ${String(this.hiddenSubCallCount)} more tool call${suffix} ...`)),
currentTheme.italic(currentTheme.dim(` ${String(this.hiddenSubCallCount)} more tool call${suffix} `)),
0,
0,
),
Expand Down Expand Up @@ -2043,7 +2043,7 @@ export class ToolCallComponent extends Container {
this.addChild(
new Text(
currentTheme.dim(
`... (${String(remaining)} more lines, ${String(allLines.length)} total, ctrl+o to expand)`,
` (${String(remaining)} more lines, ${String(allLines.length)} total, ctrl+o to expand)`,
),
2,
0,
Expand Down Expand Up @@ -2130,7 +2130,7 @@ export class ToolCallComponent extends Container {
const elapsedSeconds =
startedAtMs === undefined ? 0 : Math.max(0, Math.floor((Date.now() - startedAtMs) / 1000));
const target = filePath.length > 0 ? ` for ${filePath}` : '';
const progress = `Preparing changes${target}... ${formatByteSize(bytes)} · ${formatElapsed(
const progress = `Preparing changes${target} ${formatByteSize(bytes)} · ${formatElapsed(
elapsedSeconds,
)} elapsed`;
this.addChild(new Text(currentTheme.dim(progress), 2, 0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,15 @@ export class TruncatedOutputComponent implements Component {
if (this.tail) {
const shown = contentLines.slice(contentLines.length - this.maxLines);
return [
this.renderHint(width, `... (${String(remaining)} earlier lines)`),
this.renderHint(width, ` (${String(remaining)} earlier lines)`),
...shown,
];
}

const shown = contentLines.slice(0, this.maxLines);
const hint = this.expandHint
? `... (${String(remaining)} more lines, ctrl+o to expand)`
: `... (${String(remaining)} more lines)`;
? ` (${String(remaining)} more lines, ctrl+o to expand)`
: ` (${String(remaining)} more lines)`;
return [...shown, this.renderHint(width, hint)];
}
}
Expand Down
4 changes: 2 additions & 2 deletions apps/pythinker-code/src/tui/components/panes/btw-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class BtwPanelComponent implements Component {
lines.push(...this.renderTurn(turn, width));
}
if (this.turns.length === 0) {
lines.push(chalk.hex(currentTheme.palette.textDim)('Ready for a side question...'));
lines.push(chalk.hex(currentTheme.palette.textDim)('Ready for a side question'));
}
lines.push(...this.renderTransientNotices(width));
return this.fitBodyLines(lines);
Expand Down Expand Up @@ -213,7 +213,7 @@ export class BtwPanelComponent implements Component {
: thinkingLines;
lines.push(...visibleThinking);
} else if (turn.error === undefined) {
lines.push(chalk.hex(currentTheme.palette.textDim)('Waiting for answer...'));
lines.push(chalk.hex(currentTheme.palette.textDim)('Waiting for answer'));
}
if (turn.error !== undefined) {
const error = chalk.hex(currentTheme.palette.error)(turn.error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function normalizeBackgroundField(value: string | undefined): string | undefined
const collapsed = value.trim().replaceAll(/\s+/g, ' ');
if (collapsed.length === 0) return undefined;
if (collapsed.length <= MAX_BACKGROUND_FIELD_LENGTH) return collapsed;
return `${collapsed.slice(0, MAX_BACKGROUND_FIELD_LENGTH - 3)}...`;
return `${collapsed.slice(0, MAX_BACKGROUND_FIELD_LENGTH - 1)}…`;
}

export function formatBackgroundAgentTranscript(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function truncate(value: string | undefined): string | undefined {
const collapsed = value.trim().replaceAll(/\s+/g, ' ');
if (collapsed.length === 0) return undefined;
if (collapsed.length <= MAX_DETAIL_LENGTH) return collapsed;
return `${collapsed.slice(0, MAX_DETAIL_LENGTH - 3)}...`;
return `${collapsed.slice(0, MAX_DETAIL_LENGTH - 1)}…`;
}

export type BackgroundTaskTranscriptPhase = 'started' | 'updated' | 'terminal';
Expand Down
6 changes: 3 additions & 3 deletions apps/pythinker-code/test/tui/activity-pane.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('updateActivityPane terminal progress', () => {
expect(state.activitySpinner).not.toBeNull();
expect(state.activityContainer.children).toHaveLength(0);
const rendered = strip(progress.render(80).join('\n'));
expect(rendered).toContain('Working...');
expect(rendered).toContain('Working');
expect(BRAILLE_SPINNER_FRAMES.some((frame) => rendered.includes(frame))).toBe(true);

state.activitySpinner?.instance.stop();
Expand Down Expand Up @@ -212,8 +212,8 @@ describe('updateActivityPane terminal progress', () => {
expect(state.activitySpinner).not.toBeNull();
expect(state.activityContainer.children).toHaveLength(1);
const output = strip(progress.render(80).join('\n'));
expect(output).toContain(' Working...');
expect(output).not.toContain('⣷ Working...');
expect(output).toContain(' Working');
expect(output).not.toContain('⣷ Working');

state.activitySpinner?.instance.stop();
driver.sessionEventHandler.clearAgentDynamicWorkflowProgress();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('CompactionComponent', () => {
const lines = component.render(120).map(strip);
const text = lines.join('\n');

expect(text).toContain('Compacting context...');
expect(text).toContain('Compacting context');
expect(text).toContain(' keep the recent files only');
} finally {
component.dispose();
Expand All @@ -34,7 +34,7 @@ describe('CompactionComponent', () => {
const lines = component.render(120).map(strip);
const text = lines.join('\n');

expect(text).toContain('Compacting context... · Tip: ctrl+s: steer mid-turn');
expect(text).toContain('Compacting context · Tip: ctrl+s: steer mid-turn');
} finally {
component.dispose();
}
Expand Down Expand Up @@ -65,7 +65,7 @@ describe('CompactionComponent', () => {
const text = lines.join('\n');

expect(text).toContain('Compaction cancelled');
expect(text).not.toContain('Compacting context...');
expect(text).not.toContain('Compacting context');
} finally {
component.dispose();
}
Expand Down Expand Up @@ -157,7 +157,7 @@ describe('CompactionComponent', () => {

try {
const headerOf = (): string => {
const line = component.render(120).find((l) => strip(l).includes('Compacting context...'));
const line = component.render(120).find((l) => strip(l).includes('Compacting context'));
if (line === undefined) throw new Error('header line not found');
return line;
};
Expand Down
Loading
Loading