release: v2.0.7 - Enhanced Telegram Reporting & File Visibility (2026-05-14)
This commit is contained in:
@@ -195,6 +195,7 @@ export async function runCompanyTurn(
|
||||
outputs,
|
||||
report: reportResult.report,
|
||||
sessionTimestamp: timestamp,
|
||||
sessionDir,
|
||||
});
|
||||
telegramOk = await reporter(tgText);
|
||||
if (!telegramOk) telegramReason = 'delivery-failed';
|
||||
@@ -284,10 +285,12 @@ async function _dispatchOne(
|
||||
// hit disk / shell. The report (e.g. "✅ Created: foo.py") is
|
||||
// appended to the response so the user sees what really happened.
|
||||
let finalResponse = rawResponse || '_(empty response)_';
|
||||
let actionReport: string[] | undefined;
|
||||
const hasTag = !!rawResponse && _hasActionTag(rawResponse);
|
||||
if (rawResponse && deps.executeActionTags && hasTag) {
|
||||
try {
|
||||
const report = await deps.executeActionTags(rawResponse);
|
||||
actionReport = report;
|
||||
if (report.length > 0) {
|
||||
finalResponse = `${rawResponse}\n\n---\n**Action 실행 결과:**\n${report.map((r) => `- ${r}`).join('\n')}`;
|
||||
}
|
||||
@@ -322,6 +325,7 @@ async function _dispatchOne(
|
||||
error: rawResponse
|
||||
? (claimedButDidnt ? 'claimed-creation-no-tag' : undefined)
|
||||
: 'empty-response',
|
||||
actionReport,
|
||||
};
|
||||
} catch (e: any) {
|
||||
const err = e?.message ?? String(e);
|
||||
|
||||
@@ -105,7 +105,10 @@ export async function buildTelegramReporter(
|
||||
/**
|
||||
* Compose the per-turn Telegram message. Format mirrors Connect_origin's
|
||||
* Secretary report so users moving between the two products see consistent
|
||||
* notifications: header + brief + agent list + CEO synthesis + session id.
|
||||
* notifications: header + brief + agent list + CEO synthesis + session id +
|
||||
* **concrete file paths** so follow-up questions like "어디에 만들었어?"
|
||||
* have a clean answer (the bot's previous answer "I don't have file system
|
||||
* access" was the user-visible bug we're fixing here).
|
||||
*
|
||||
* The function is pure (no I/O) and exported separately so it can be unit-
|
||||
* tested without touching VS Code APIs.
|
||||
@@ -117,6 +120,9 @@ export function formatCompanyTelegramReport(opts: {
|
||||
outputs: AgentTurnOutput[];
|
||||
report: string;
|
||||
sessionTimestamp: string;
|
||||
/** Absolute path of the session directory — surfaced in the report so
|
||||
* the user can locate generated files without asking the bot again. */
|
||||
sessionDir: string;
|
||||
}): string {
|
||||
const company = opts.state.companyName || '1인 기업';
|
||||
const header = `*📱 ${company} — 작업 라운드 보고*`;
|
||||
@@ -130,9 +136,33 @@ export function formatCompanyTelegramReport(opts: {
|
||||
return `• ${mark} ${def?.emoji ?? ''} ${def?.name ?? t.agent}`;
|
||||
}).join('\n')
|
||||
: '';
|
||||
// Concrete artefacts: extract the file paths the action-tag executor
|
||||
// actually wrote, so the user can copy-paste them into Finder or `cd` to
|
||||
// the right place. Empty when no agent emitted file/command tags.
|
||||
const artefactsLine = _formatArtefactsBlock(opts.outputs);
|
||||
const reportBody = opts.report.trim()
|
||||
? `\n\n${opts.report.trim().slice(0, REPORT_BUDGET)}`
|
||||
: '';
|
||||
const sessionLine = `\n\n_세션: ${opts.sessionTimestamp}_`;
|
||||
return `${header}\n\n${cmdLine}${brief}${agentsLine}${reportBody}${sessionLine}`;
|
||||
const sessionLine = `\n\n*세션 폴더:* \`${opts.sessionDir}\``;
|
||||
return `${header}\n\n${cmdLine}${brief}${agentsLine}${artefactsLine}${reportBody}${sessionLine}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull a `*결과물:*` block out of the per-agent action reports. The
|
||||
* executor emits lines like `"✅ Created: testtimer/timer.py"` —
|
||||
* we re-format them with the workspace-relative path intact so the user
|
||||
* can `cd <workspace>/testtimer` and find the file.
|
||||
*/
|
||||
function _formatArtefactsBlock(outputs: AgentTurnOutput[]): string {
|
||||
const lines: string[] = [];
|
||||
for (const out of outputs) {
|
||||
if (!out.actionReport || out.actionReport.length === 0) continue;
|
||||
for (const r of out.actionReport) {
|
||||
// Keep success lines verbatim; trim long shell-output blocks.
|
||||
const trimmed = r.length > 200 ? r.slice(0, 200) + '…' : r;
|
||||
lines.push(`• ${trimmed}`);
|
||||
}
|
||||
}
|
||||
if (lines.length === 0) return '';
|
||||
return '\n\n*결과물:*\n' + lines.join('\n');
|
||||
}
|
||||
|
||||
@@ -101,6 +101,13 @@ export interface AgentTurnOutput {
|
||||
durationMs: number;
|
||||
/** Populated when the dispatch failed; `response` then holds the error. */
|
||||
error?: string;
|
||||
/**
|
||||
* Lines returned by the action-tag executor — e.g. `"✅ Created: testtimer/timer.py"`.
|
||||
* Kept separate from `response` so downstream surfaces (Telegram mirror,
|
||||
* sidebar chip) can extract concrete file paths instead of regex-scraping
|
||||
* the prose. Empty / absent when the agent emitted no action tags.
|
||||
*/
|
||||
actionReport?: string[];
|
||||
}
|
||||
|
||||
/** The whole result of a company turn — persisted under sessions/<timestamp>/. */
|
||||
|
||||
Reference in New Issue
Block a user