{"version":3,"file":"interactive-mode-footer-integration.test.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-mode-footer-integration.test.ts"],"names":[],"mappings":"","sourcesContent":["import { Container } from \"@apholdings/jensen-tui\";\nimport stripAnsi from \"strip-ansi\";\nimport { beforeAll, describe, expect, it, vi } from \"vitest\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { ReadonlyFooterDataProvider } from \"../../core/footer-data-provider.js\";\nimport type { SessionContext } from \"../../core/session-manager.js\";\nimport { BashExecutionComponent } from \"./components/bash-execution.js\";\nimport { FooterComponent } from \"./components/footer.js\";\nimport { InteractiveMode } from \"./interactive-mode.js\";\nimport { getMarkdownTheme, initTheme } from \"./theme/theme.js\";\n\nbeforeAll(() => {\n\tinitTheme(\"dark\");\n});\n\nfunction createFooterData(): ReadonlyFooterDataProvider {\n\treturn {\n\t\tgetGitRepoName: () => \"jensen-code\",\n\t\tgetGitBranch: () => \"main\",\n\t\tgetExtensionStatuses: () => new Map(),\n\t\tonBranchChange: () => () => {},\n\t\tgetAvailableProviderCount: () => 0,\n\t};\n}\n\ndescribe(\"InteractiveMode footer cost integration\", () => {\n\tit(\"renders turn and session cost from a real multi-turn session history using the current bash/user turn boundary semantics\", () => {\n\t\tconst messages = [\n\t\t\t{\n\t\t\t\trole: \"user\",\n\t\t\t\tcontent: [{ type: \"text\", text: \"first turn\" }],\n\t\t\t},\n\t\t\t{\n\t\t\t\trole: \"assistant\",\n\t\t\t\tprovider: \"openrouter\",\n\t\t\t\tmodel: \"ai21/jamba-large-1.7\",\n\t\t\t\tcontent: [{ type: \"text\", text: \"first answer\" }],\n\t\t\t\tusage: {\n\t\t\t\t\tinput: 1000,\n\t\t\t\t\toutput: 500,\n\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\ttotalTokens: 1500,\n\t\t\t\t},\n\t\t\t\tstopReason: \"end_turn\",\n\t\t\t\ttimestamp: 1,\n\t\t\t},\n\t\t\t{\n\t\t\t\trole: \"bashExecution\",\n\t\t\t\tcommand: \"pwd\",\n\t\t\t\toutput: \"/home/magnus/software/jensen-code\",\n\t\t\t\texitCode: 0,\n\t\t\t\tcancelled: false,\n\t\t\t\ttruncated: false,\n\t\t\t\ttimestamp: 2,\n\t\t\t},\n\t\t\t{\n\t\t\t\trole: \"assistant\",\n\t\t\t\tprovider: \"openrouter\",\n\t\t\t\tmodel: \"ai21/jamba-large-1.7\",\n\t\t\t\tcontent: [{ type: \"text\", text: \"second answer after bash\" }],\n\t\t\t\tusage: {\n\t\t\t\t\tinput: 500,\n\t\t\t\t\toutput: 250,\n\t\t\t\t\tcacheRead: 0,\n\t\t\t\t\tcacheWrite: 0,\n\t\t\t\t\ttotalTokens: 750,\n\t\t\t\t},\n\t\t\t\tstopReason: \"end_turn\",\n\t\t\t\ttimestamp: 3,\n\t\t\t},\n\t\t] as AgentSession[\"state\"][\"messages\"];\n\n\t\tconst session = {\n\t\t\tstate: {\n\t\t\t\tmessages,\n\t\t\t\tmodel: null,\n\t\t\t},\n\t\t\tbriefOnly: false,\n\t\t\textensionRunner: undefined,\n\t\t\tsettingsManager: { getShowImages: () => false },\n\t\t\tgetContextUsage: () => ({ tokens: 1200, contextWindow: 128000, percent: 0.9375 }),\n\t\t} as unknown as AgentSession;\n\n\t\tconst mode = Object.assign(Object.create(InteractiveMode.prototype), {\n\t\t\tpendingTools: new Map(),\n\t\t\tchatContainer: new Container(),\n\t\t\tfooter: new FooterComponent(session, createFooterData()),\n\t\t\tupdatePromptChrome: vi.fn(),\n\t\t\tui: { requestRender: vi.fn(), terminal: { columns: 160 } },\n\t\t\tgetRegisteredToolDefinition: () => undefined,\n\t\t\ttoolOutputExpanded: false,\n\t\t\tsession,\n\t\t\thideThinkingBlock: false,\n\t\t\tgetMarkdownThemeWithSettings: () => getMarkdownTheme(),\n\t\t}) as unknown as {\n\t\t\trenderSessionContext: (\n\t\t\t\tcontext: SessionContext,\n\t\t\t\toptions?: { updateFooter?: boolean; populateHistory?: boolean },\n\t\t\t) => void;\n\t\t\tchatContainer: Container;\n\t\t\tfooter: FooterComponent;\n\t\t};\n\n\t\tmode.renderSessionContext(\n\t\t\t{\n\t\t\t\tmessages: messages as SessionContext[\"messages\"],\n\t\t\t\tthinkingLevel: \"off\",\n\t\t\t\tmodel: null,\n\t\t\t\tmemoryItems: [],\n\t\t\t\ttodos: [],\n\t\t\t},\n\t\t\t{ updateFooter: true },\n\t\t);\n\n\t\texpect(mode.chatContainer.children.some((child) => child instanceof BashExecutionComponent)).toBe(true);\n\n\t\tconst line = stripAnsi(mode.footer.render(160)[0] ?? \"\");\n\t\texpect(line).toContain(\"cost turn $0.003000 · session $0.009000\");\n\t});\n});\n"]}