SYMBOL INDEX (2841 symbols across 352 files) FILE: console/src/App.tsx function AuthGuard (line 45) | function AuthGuard({ children }: { children: React.ReactNode }) { function getRouterBasename (line 102) | function getRouterBasename(pathname: string): string | undefined { function AppInner (line 106) | function AppInner() { function App (line 162) | function App() { FILE: console/src/api/config.ts constant AUTH_TOKEN_KEY (line 4) | const AUTH_TOKEN_KEY = "copaw_auth_token"; function getApiUrl (line 11) | function getApiUrl(path: string): string { function getApiToken (line 23) | function getApiToken(): string { function setAuthToken (line 32) | function setAuthToken(token: string): void { function clearAuthToken (line 39) | function clearAuthToken(): void { FILE: console/src/api/modules/auth.ts type LoginResponse (line 3) | interface LoginResponse { type AuthStatusResponse (line 9) | interface AuthStatusResponse { FILE: console/src/api/modules/chat.ts type ChatUploadResponse (line 11) | interface ChatUploadResponse { constant CONSOLE_FILES_PREFIX (line 17) | const CONSOLE_FILES_PREFIX = "/console/files"; function buildChatUploadHeaders (line 19) | function buildChatUploadHeaders(): HeadersInit { function getSelectedAgentId (line 36) | function getSelectedAgentId(): string { FILE: console/src/api/modules/console.ts type PushMessage (line 3) | interface PushMessage { FILE: console/src/api/modules/security.ts type ToolGuardRule (line 3) | interface ToolGuardRule { type ToolGuardConfig (line 15) | interface ToolGuardConfig { type SkillScannerWhitelistEntry (line 25) | interface SkillScannerWhitelistEntry { type SkillScannerMode (line 31) | type SkillScannerMode = "block" | "warn" | "off"; type SkillScannerConfig (line 33) | interface SkillScannerConfig { type BlockedSkillFinding (line 39) | interface BlockedSkillFinding { type BlockedSkillRecord (line 48) | interface BlockedSkillRecord { type SecurityScanErrorResponse (line 57) | interface SecurityScanErrorResponse { FILE: console/src/api/modules/skill.ts function getStreamApiUrl (line 9) | function getStreamApiUrl(): string { function buildHeaders (line 14) | function buildHeaders(): HeadersInit { FILE: console/src/api/modules/tokenUsage.ts type GetTokenUsageParams (line 4) | interface GetTokenUsageParams { function buildQuery (line 9) | function buildQuery(params: GetTokenUsageParams): string { FILE: console/src/api/modules/tools.ts type ToolInfo (line 3) | interface ToolInfo { FILE: console/src/api/modules/userTimezone.ts type UserTimezoneConfig (line 3) | interface UserTimezoneConfig { FILE: console/src/api/modules/workspace.ts function buildHeaders (line 5) | function buildHeaders(): HeadersInit { function getSelectedAgentId (line 29) | function getSelectedAgentId(): string { function generateFallbackFilename (line 45) | function generateFallbackFilename(): string { type WorkspaceDownloadResult (line 57) | interface WorkspaceDownloadResult { FILE: console/src/api/request.ts function buildHeaders (line 3) | function buildHeaders(method?: string, extra?: HeadersInit): Headers { function request (line 39) | async function request( FILE: console/src/api/types/agent.ts type AgentRequest (line 1) | interface AgentRequest { type AgentsRunningConfig (line 9) | interface AgentsRunningConfig { FILE: console/src/api/types/agents.ts type AgentSummary (line 3) | interface AgentSummary { type AgentListResponse (line 10) | interface AgentListResponse { type AgentProfileConfig (line 14) | interface AgentProfileConfig { type CreateAgentRequest (line 29) | interface CreateAgentRequest { type AgentProfileRef (line 36) | interface AgentProfileRef { FILE: console/src/api/types/channel.ts type BaseChannelConfig (line 1) | interface BaseChannelConfig { type IMessageChannelConfig (line 12) | interface IMessageChannelConfig extends BaseChannelConfig { type DiscordConfig (line 17) | interface DiscordConfig extends BaseChannelConfig { type DingTalkConfig (line 23) | interface DingTalkConfig extends BaseChannelConfig { type FeishuConfig (line 32) | interface FeishuConfig extends BaseChannelConfig { type QQConfig (line 40) | interface QQConfig extends BaseChannelConfig { type TelegramConfig (line 45) | interface TelegramConfig extends BaseChannelConfig { type MQTTConfig (line 52) | interface MQTTConfig extends BaseChannelConfig { type MatrixConfig (line 68) | interface MatrixConfig extends BaseChannelConfig { type ConsoleConfig (line 74) | type ConsoleConfig = BaseChannelConfig; type VoiceChannelConfig (line 76) | interface VoiceChannelConfig extends BaseChannelConfig { type XiaoYiConfig (line 88) | interface XiaoYiConfig extends BaseChannelConfig { type ChannelConfig (line 96) | interface ChannelConfig { type SingleChannelConfig (line 110) | type SingleChannelConfig = FILE: console/src/api/types/chat.ts type ChatStatus (line 1) | type ChatStatus = "idle" | "running"; type ChatSpec (line 3) | interface ChatSpec { type Message (line 14) | interface Message { type ChatHistory (line 20) | interface ChatHistory { type ChatDeleteResponse (line 25) | interface ChatDeleteResponse { type Session (line 31) | type Session = ChatSpec; FILE: console/src/api/types/cronjob.ts type CronJobSchedule (line 1) | interface CronJobSchedule { type CronJobTarget (line 7) | interface CronJobTarget { type CronJobDispatch (line 12) | interface CronJobDispatch { type CronJobRuntime (line 20) | interface CronJobRuntime { type CronJobRequest (line 26) | interface CronJobRequest { type CronJobSpecInput (line 33) | interface CronJobSpecInput { type CronJobSpecOutput (line 46) | type CronJobSpecOutput = CronJobSpecInput; type CronJobView (line 48) | interface CronJobView extends CronJobSpecOutput { type CronJobSpecInputLegacy (line 55) | type CronJobSpecInputLegacy = Record; type CronJobSpecOutputLegacy (line 56) | type CronJobSpecOutputLegacy = Record; type CronJobViewLegacy (line 57) | type CronJobViewLegacy = Record; FILE: console/src/api/types/env.ts type EnvVar (line 1) | interface EnvVar { FILE: console/src/api/types/heartbeat.ts type ActiveHoursConfig (line 1) | interface ActiveHoursConfig { type HeartbeatConfig (line 6) | interface HeartbeatConfig { FILE: console/src/api/types/mcp.ts type MCPClientInfo (line 5) | interface MCPClientInfo { type MCPClientCreateRequest (line 30) | interface MCPClientCreateRequest { type MCPClientUpdateRequest (line 58) | interface MCPClientUpdateRequest { FILE: console/src/api/types/provider.ts type ModelInfo (line 1) | interface ModelInfo { type ProviderInfo (line 6) | interface ProviderInfo { type ProviderConfigRequest (line 30) | interface ProviderConfigRequest { type ModelSlotConfig (line 37) | interface ModelSlotConfig { type ActiveModelsInfo (line 42) | interface ActiveModelsInfo { type ModelSlotRequest (line 46) | interface ModelSlotRequest { type CreateCustomProviderRequest (line 53) | interface CreateCustomProviderRequest { type AddModelRequest (line 62) | interface AddModelRequest { type LocalModelResponse (line 69) | interface LocalModelResponse { type DownloadModelRequest (line 80) | interface DownloadModelRequest { type DownloadTaskResponse (line 87) | interface DownloadTaskResponse { type OllamaModelResponse (line 100) | interface OllamaModelResponse { type OllamaDownloadRequest (line 107) | interface OllamaDownloadRequest { type OllamaDownloadTaskResponse (line 111) | interface OllamaDownloadTaskResponse { type TestConnectionResponse (line 121) | interface TestConnectionResponse { type TestProviderRequest (line 126) | interface TestProviderRequest { type TestModelRequest (line 133) | interface TestModelRequest { type DiscoverModelsResponse (line 137) | interface DiscoverModelsResponse { FILE: console/src/api/types/skill.ts type SkillSpec (line 1) | interface SkillSpec { type HubSkillSpec (line 10) | interface HubSkillSpec { type Skill (line 19) | interface Skill { FILE: console/src/api/types/tokenUsage.ts type TokenUsageStats (line 2) | interface TokenUsageStats { type TokenUsageSummary (line 10) | interface TokenUsageSummary { FILE: console/src/api/types/workspace.ts type MdFileInfo (line 1) | interface MdFileInfo { type MdFileContent (line 9) | interface MdFileContent { type MarkdownFile (line 13) | interface MarkdownFile extends MdFileInfo { type DailyMemoryFile (line 18) | interface DailyMemoryFile extends MdFileInfo { FILE: console/src/components/AgentSelector/index.tsx function AgentSelector (line 9) | function AgentSelector() { FILE: console/src/components/ConsoleCronBubble/index.tsx constant POLL_INTERVAL_MS (line 6) | const POLL_INTERVAL_MS = 2500; constant AUTO_DISMISS_MS (line 7) | const AUTO_DISMISS_MS = 8000; constant MAX_SEEN_IDS (line 8) | const MAX_SEEN_IDS = 500; constant MAX_VISIBLE_BUBBLES (line 9) | const MAX_VISIBLE_BUBBLES = 4; constant MAX_NEW_PER_POLL (line 10) | const MAX_NEW_PER_POLL = 2; constant TITLE_BLINK_PREFIX (line 11) | const TITLE_BLINK_PREFIX = "\u2022 "; type BubbleItem (line 13) | interface BubbleItem extends PushMessage { function ConsoleCronBubble (line 17) | function ConsoleCronBubble() { FILE: console/src/components/LanguageSwitcher.tsx function LanguageSwitcher (line 6) | function LanguageSwitcher() { FILE: console/src/components/MarkdownCopy/MarkdownCopy.tsx type MarkdownCopyProps (line 10) | interface MarkdownCopyProps { function MarkdownCopy (line 43) | function MarkdownCopy({ FILE: console/src/components/ThemeToggleButton/index.tsx function ThemeToggleButton (line 11) | function ThemeToggleButton() { FILE: console/src/constants/timezone.ts constant TIMEZONE_OPTIONS (line 1) | const TIMEZONE_OPTIONS = [ FILE: console/src/contexts/ThemeContext.tsx type ThemeMode (line 10) | type ThemeMode = "light" | "dark" | "system"; type ResolvedTheme (line 11) | type ResolvedTheme = "light" | "dark"; constant STORAGE_KEY (line 13) | const STORAGE_KEY = "copaw-theme"; type ThemeContextValue (line 15) | interface ThemeContextValue { function getInitialMode (line 32) | function getInitialMode(): ThemeMode { function resolveIsDark (line 44) | function resolveIsDark(mode: ThemeMode): boolean { function ThemeProvider (line 51) | function ThemeProvider({ children }: { children: ReactNode }) { function useTheme (line 102) | function useTheme(): ThemeContextValue { FILE: console/src/layouts/Header.tsx type HeaderProps (line 24) | interface HeaderProps { function Header (line 28) | function Header({ selectedKey }: HeaderProps) { FILE: console/src/layouts/MainLayout/index.tsx function MainLayout (line 45) | function MainLayout() { FILE: console/src/layouts/Sidebar.tsx type SidebarProps (line 64) | interface SidebarProps { function CopyButton (line 70) | function CopyButton({ text }: { text: string }) { function Sidebar (line 100) | function Sidebar({ selectedKey }: SidebarProps) { FILE: console/src/layouts/constants.ts constant PYPI_URL (line 3) | const PYPI_URL = "https://pypi.org/pypi/copaw/json"; constant GITHUB_URL (line 5) | const GITHUB_URL = "https://github.com/agentscope-ai/CoPaw" as const; constant ONE_HOUR_MS (line 9) | const ONE_HOUR_MS = 60 * 60 * 1000; constant DEFAULT_OPEN_KEYS (line 13) | const DEFAULT_OPEN_KEYS = [ constant KEY_TO_PATH (line 20) | const KEY_TO_PATH: Record = { constant KEY_TO_LABEL (line 39) | const KEY_TO_LABEL: Record = { constant UPDATE_MD (line 98) | const UPDATE_MD: Record = { FILE: console/src/pages/Agent/Config/components/ContextManagementCard.tsx type ContextManagementCardProps (line 6) | interface ContextManagementCardProps { function ContextManagementCard (line 11) | function ContextManagementCard({ FILE: console/src/pages/Agent/Config/components/PageHeader.tsx function PageHeader (line 4) | function PageHeader() { FILE: console/src/pages/Agent/Config/components/ReactAgentCard.tsx constant LANGUAGE_OPTIONS (line 6) | const LANGUAGE_OPTIONS = [ type ReactAgentCardProps (line 12) | interface ReactAgentCardProps { function ReactAgentCard (line 21) | function ReactAgentCard({ FILE: console/src/pages/Agent/Config/components/SliderWithValue.tsx type SliderWithValueProps (line 3) | interface SliderWithValueProps { function SliderWithValue (line 12) | function SliderWithValue({ FILE: console/src/pages/Agent/Config/index.tsx function AgentConfigPage (line 12) | function AgentConfigPage() { FILE: console/src/pages/Agent/Config/useAgentConfig.tsx function useAgentConfig (line 7) | function useAgentConfig() { FILE: console/src/pages/Agent/MCP/components/MCPClientCard.tsx type MCPClientCardProps (line 10) | interface MCPClientCardProps { function MCPClientCard (line 20) | function MCPClientCard({ FILE: console/src/pages/Agent/MCP/components/MCPClientDrawer.tsx type MCPClientDrawerProps (line 6) | interface MCPClientDrawerProps { function MCPClientDrawer (line 27) | function MCPClientDrawer({ FILE: console/src/pages/Agent/MCP/index.tsx type MCPTransport (line 8) | type MCPTransport = "stdio" | "streamable_http" | "sse"; function normalizeTransport (line 10) | function normalizeTransport(raw?: unknown): MCPTransport | undefined { function normalizeClientData (line 28) | function normalizeClientData(key: string, rawData: any) { function MCPPage (line 52) | function MCPPage() { FILE: console/src/pages/Agent/MCP/useMCP.ts function useMCP (line 8) | function useMCP() { FILE: console/src/pages/Agent/Skills/components/SkillCard.tsx type SkillCardProps (line 17) | interface SkillCardProps { function SkillCard (line 77) | function SkillCard({ FILE: console/src/pages/Agent/Skills/components/SkillDrawer.tsx function parseFrontmatter (line 14) | function parseFrontmatter(content: string): Record | null { type SkillDrawerProps (line 36) | interface SkillDrawerProps { function SkillDrawer (line 45) | function SkillDrawer({ FILE: console/src/pages/Agent/Skills/index.tsx function SkillsPage (line 14) | function SkillsPage() { FILE: console/src/pages/Agent/Skills/useSkills.ts function tryParseScanError (line 10) | function tryParseScanError(error: unknown): SecurityScanErrorResponse | ... function useSkills (line 26) | function useSkills() { FILE: console/src/pages/Agent/Tools/index.tsx function ToolsPage (line 8) | function ToolsPage() { FILE: console/src/pages/Agent/Tools/useTools.ts function useTools (line 8) | function useTools() { FILE: console/src/pages/Agent/Workspace/components/FileEditor.tsx type FileEditorProps (line 10) | interface FileEditorProps { FILE: console/src/pages/Agent/Workspace/components/FileItem.tsx type FileItemProps (line 15) | interface FileItemProps { FILE: console/src/pages/Agent/Workspace/components/FileListPanel.tsx type FileListPanelProps (line 22) | interface FileListPanelProps { FILE: console/src/pages/Agent/Workspace/index.tsx function WorkspacePage (line 9) | function WorkspacePage() { FILE: console/src/pages/Chat/ModelSelector/index.tsx type EligibleProvider (line 15) | interface EligibleProvider { function ModelSelector (line 21) | function ModelSelector() { FILE: console/src/pages/Chat/OptionsPanel/FormItem.tsx type FormItemProps (line 4) | interface FormItemProps { function FormItem (line 20) | function FormItem(props: FormItemProps) { FILE: console/src/pages/Chat/OptionsPanel/OptionsEditor.tsx type OptionsEditorProps (line 31) | interface OptionsEditorProps { FILE: console/src/pages/Chat/OptionsPanel/defaultConfig.ts function getDefaultConfig (line 38) | function getDefaultConfig(t: TFunction) { type DefaultConfig (line 56) | type DefaultConfig = typeof defaultConfig; FILE: console/src/pages/Chat/OptionsPanel/index.tsx type OptionsPanelProps (line 6) | interface OptionsPanelProps { function OptionsPanel (line 11) | function OptionsPanel(props: OptionsPanelProps) { FILE: console/src/pages/Chat/index.tsx type CopyableContent (line 31) | type CopyableContent = { type CopyableMessage (line 37) | type CopyableMessage = { type CopyableResponse (line 42) | type CopyableResponse = { type RuntimeUiMessage (line 46) | type RuntimeUiMessage = IAgentScopeRuntimeWebUIMessage & { type StreamResponseData (line 56) | type StreamResponseData = { type RuntimeLoadingBridgeApi (line 63) | type RuntimeLoadingBridgeApi = { type CustomWindow (line 68) | interface CustomWindow extends Window { function extractCopyableText (line 76) | function extractCopyableText(response: CopyableResponse): string { function copyText (line 108) | async function copyText(text: string) { function buildModelError (line 135) | function buildModelError(): Response { function cloneRuntimeMessages (line 145) | function cloneRuntimeMessages( function cloneValue (line 151) | function cloneValue(value: T): T { function isFinalResponseStatus (line 155) | function isFinalResponseStatus(status?: string): boolean { function hasRenderableOutput (line 163) | function hasRenderableOutput(response: StreamResponseData): boolean { function getResponseCardData (line 174) | function getResponseCardData( function getStreamingAssistantMessageId (line 188) | function getStreamingAssistantMessageId( function RuntimeLoadingBridge (line 206) | function RuntimeLoadingBridge({ function ChatPage (line 240) | function ChatPage() { FILE: console/src/pages/Chat/sessionApi/index.ts constant DEFAULT_USER_ID (line 16) | const DEFAULT_USER_ID = "default"; constant DEFAULT_CHANNEL (line 17) | const DEFAULT_CHANNEL = "console"; constant DEFAULT_SESSION_NAME (line 18) | const DEFAULT_SESSION_NAME = "New Chat"; constant ROLE_TOOL (line 19) | const ROLE_TOOL = "tool"; constant ROLE_USER (line 20) | const ROLE_USER = "user"; constant ROLE_ASSISTANT (line 21) | const ROLE_ASSISTANT = "assistant"; constant TYPE_PLUGIN_CALL_OUTPUT (line 22) | const TYPE_PLUGIN_CALL_OUTPUT = "plugin_call_output"; constant CARD_RESPONSE (line 24) | const CARD_RESPONSE = "AgentScopeRuntimeResponseCard"; type CustomWindow (line 30) | interface CustomWindow extends Window { type ContentItem (line 43) | interface ContentItem { type OutputMessage (line 50) | interface OutputMessage extends Omit { type ExtendedSession (line 60) | interface ExtendedSession extends IAgentScopeRuntimeWebUISession { type RuntimeResponseCard (line 71) | interface RuntimeResponseCard { constant LIVE_MESSAGE_STATUSES (line 77) | const LIVE_MESSAGE_STATUSES = new Set(["generating", "created", "in_prog... function generateId (line 126) | function generateId(): string { function toDisplayUrl (line 131) | function toDisplayUrl(url: string | undefined): string { function contentToRequestParts (line 138) | function contentToRequestParts( function buildUserCard (line 186) | function buildUserCard(msg: Message): IAgentScopeRuntimeWebUIMessage { class SessionApi (line 317) | class SessionApi implements IAgentScopeRuntimeWebUISessionAPI { method findSessionIndexByAnyId (line 321) | private findSessionIndexByAnyId(sessionId?: string | null): number { method findSessionByAnyId (line 336) | private findSessionByAnyId( method cacheSession (line 343) | private cacheSession(session: ExtendedSession): void { method setChatRef (line 394) | setChatRef(ref: RefObject | null): void { method triggerReconnectSubmit (line 403) | triggerReconnectSubmit(): void { method resolveRealIdInBackground (line 417) | private resolveRealIdInBackground(tempId: string): void { method createEmptySession (line 436) | private createEmptySession(sessionId: string): ExtendedSession { method updateWindowVariables (line 451) | private updateWindowVariables(session: ExtendedSession): void { method getLocalSession (line 457) | private getLocalSession(sessionId: string): IAgentScopeRuntimeWebUISes... method getRealIdForSession (line 470) | getRealIdForSession(sessionId: string): string | null { method hasLiveMessagesForSession (line 475) | hasLiveMessagesForSession(sessionId?: string | null): boolean { method getSessionList (line 479) | async getSessionList() { method getSession (line 545) | async getSession(sessionId: string) { method _doGetSession (line 565) | private async _doGetSession( method updateSession (line 653) | async updateSession(session: Partial) { method createSession (line 698) | async createSession(session: Partial) { method removeSession (line 714) | async removeSession(session: Partial) { FILE: console/src/pages/Control/Channels/components/ChannelCard.tsx type ChannelCardProps (line 6) | interface ChannelCardProps { function ChannelCard (line 15) | function ChannelCard({ FILE: console/src/pages/Control/Channels/components/ChannelDrawer.tsx constant WECOM_SDK_URL (line 20) | const WECOM_SDK_URL = constant WECOM_SOURCE (line 23) | const WECOM_SOURCE = "copaw"; type WecomBotInfo (line 25) | interface WecomBotInfo { type WecomAuthError (line 30) | interface WecomAuthError { type Window (line 37) | interface Window { constant CHANNELS_WITH_ACCESS_CONTROL (line 48) | const CHANNELS_WITH_ACCESS_CONTROL: ChannelKey[] = [ constant CHANNEL_DOC_EN_URLS (line 59) | const CHANNEL_DOC_EN_URLS: Partial> = { constant CHANNEL_DOC_ZH_URLS (line 77) | const CHANNEL_DOC_ZH_URLS: Partial> = { constant TWILIO_CONSOLE_URL (line 93) | const TWILIO_CONSOLE_URL = "https://console.twilio.com"; constant BASE_FIELDS (line 95) | const BASE_FIELDS = [ type ChannelDrawerProps (line 103) | interface ChannelDrawerProps { function ChannelDrawer (line 115) | function ChannelDrawer({ FILE: console/src/pages/Control/Channels/components/constants.ts type ChannelKey (line 2) | type ChannelKey = string; constant CHANNEL_LABELS (line 5) | const CHANNEL_LABELS: Record = { function getChannelLabel (line 22) | function getChannelLabel(key: string): string { FILE: console/src/pages/Control/Channels/index.tsx type FilterType (line 15) | type FilterType = "all" | "builtin" | "custom"; function ChannelsPage (line 17) | function ChannelsPage() { FILE: console/src/pages/Control/Channels/useChannels.ts function useChannels (line 5) | function useChannels() { FILE: console/src/pages/Control/CronJobs/components/JobDrawer.tsx type CronJob (line 18) | type CronJob = CronJobSpecOutput; type JobDrawerProps (line 20) | interface JobDrawerProps { function JobDrawer (line 29) | function JobDrawer({ FILE: console/src/pages/Control/CronJobs/components/columns.tsx type CronJob (line 10) | type CronJob = CronJobSpecOutput; type ColumnHandlers (line 12) | interface ColumnHandlers { FILE: console/src/pages/Control/CronJobs/components/constants.ts constant DEFAULT_FORM_VALUES (line 5) | const DEFAULT_FORM_VALUES = { FILE: console/src/pages/Control/CronJobs/components/parseCron.ts type CronType (line 10) | type CronType = "hourly" | "daily" | "weekly" | "custom"; type CronParts (line 12) | interface CronParts { constant CRON_RE (line 20) | const CRON_RE = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/; constant INTEGER_RE (line 21) | const INTEGER_RE = /^\d+$/; constant ORDERED_DAYS (line 27) | const ORDERED_DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] a... type DayName (line 28) | type DayName = (typeof ORDERED_DAYS)[number]; constant NUM_TO_NAME (line 30) | const NUM_TO_NAME: Record = { constant VALID_NAMES (line 41) | const VALID_NAMES = new Set(ORDERED_DAYS); function isDayName (line 43) | function isDayName(value: string): value is DayName { function parseCron (line 55) | function parseCron(cron: string): CronParts { function parsePlainCronNumber (line 104) | function parsePlainCronNumber( function serializeCron (line 124) | function serializeCron(parts: CronParts): string { function parseDaysOfWeek (line 158) | function parseDaysOfWeek(dayOfWeek: string): string[] { function serializeDaysOfWeek (line 221) | function serializeDaysOfWeek(daysOfWeek?: string[]): string { FILE: console/src/pages/Control/CronJobs/index.tsx type CronJob (line 16) | type CronJob = CronJobSpecOutput; function CronJobsPage (line 18) | function CronJobsPage() { FILE: console/src/pages/Control/CronJobs/useCronJobs.ts type CronJob (line 7) | type CronJob = CronJobSpecOutput; function useCronJobs (line 9) | function useCronJobs() { FILE: console/src/pages/Control/Heartbeat/index.tsx constant TIME_FORMAT (line 23) | const TIME_FORMAT = "HH:mm"; function TimePickerHHmm (line 26) | function TimePickerHHmm({ type HeartbeatFormValues (line 51) | type HeartbeatFormValues = Omit & { constant TARGET_OPTIONS (line 60) | const TARGET_OPTIONS = [ constant EVERY_UNIT_OPTIONS (line 65) | const EVERY_UNIT_OPTIONS: { value: EveryUnit; labelKey: string }[] = [ function HeartbeatPage (line 70) | function HeartbeatPage() { FILE: console/src/pages/Control/Heartbeat/parseEvery.ts constant EVERY_RE (line 6) | const EVERY_RE = type EveryUnit (line 9) | type EveryUnit = "m" | "h"; type EveryParts (line 11) | interface EveryParts { function parseEvery (line 16) | function parseEvery(every: string): EveryParts { function serializeEvery (line 38) | function serializeEvery(parts: EveryParts): string { FILE: console/src/pages/Control/Sessions/components/FilterBar.tsx type FilterBarProps (line 5) | interface FilterBarProps { function FilterBar (line 13) | function FilterBar({ FILE: console/src/pages/Control/Sessions/components/SessionDrawer.tsx type SessionDrawerProps (line 7) | interface SessionDrawerProps { function SessionDrawer (line 16) | function SessionDrawer({ FILE: console/src/pages/Control/Sessions/components/columns.tsx type ColumnHandlers (line 7) | interface ColumnHandlers { FILE: console/src/pages/Control/Sessions/components/constants.ts type Session (line 3) | interface Session extends ChatSpec { constant CHANNEL_COLORS (line 7) | const CHANNEL_COLORS: Record = { FILE: console/src/pages/Control/Sessions/index.tsx function SessionsPage (line 21) | function SessionsPage() { FILE: console/src/pages/Control/Sessions/useSessions.ts function useSessions (line 7) | function useSessions() { FILE: console/src/pages/Login/index.tsx function LoginPage (line 9) | function LoginPage() { FILE: console/src/pages/Settings/Agents/components/AgentModal.tsx type AgentModalProps (line 5) | interface AgentModalProps { function AgentModal (line 13) | function AgentModal({ FILE: console/src/pages/Settings/Agents/components/AgentTable.tsx type AgentTableProps (line 9) | interface AgentTableProps { function AgentTable (line 16) | function AgentTable({ FILE: console/src/pages/Settings/Agents/components/PageHeader.tsx type PageHeaderProps (line 3) | interface PageHeaderProps { function PageHeader (line 10) | function PageHeader({ FILE: console/src/pages/Settings/Agents/index.tsx function AgentsPage (line 11) | function AgentsPage() { FILE: console/src/pages/Settings/Agents/useAgents.ts type UseAgentsReturn (line 8) | interface UseAgentsReturn { function useAgents (line 16) | function useAgents(): UseAgentsReturn { FILE: console/src/pages/Settings/Environments/components/AddButton.tsx type AddButtonProps (line 5) | interface AddButtonProps { function AddButton (line 10) | function AddButton({ onClick, className }: AddButtonProps) { FILE: console/src/pages/Settings/Environments/components/EmptyState.tsx type EmptyStateProps (line 4) | interface EmptyStateProps { function EmptyState (line 8) | function EmptyState({ className }: EmptyStateProps) { FILE: console/src/pages/Settings/Environments/components/EnvRow.tsx type Row (line 8) | interface Row { type EnvRowProps (line 14) | interface EnvRowProps { function EnvRow (line 25) | function EnvRow({ FILE: console/src/pages/Settings/Environments/components/PageHeader.tsx type PageHeaderProps (line 4) | interface PageHeaderProps { function PageHeader (line 8) | function PageHeader({ className }: PageHeaderProps) { FILE: console/src/pages/Settings/Environments/components/Toolbar.tsx type ToolbarProps (line 6) | interface ToolbarProps { function Toolbar (line 21) | function Toolbar({ FILE: console/src/pages/Settings/Environments/index.tsx function shiftIndices (line 22) | function shiftIndices(prev: Set, removedIdx: number): Set { function EnvironmentsPage (line 35) | function EnvironmentsPage() { FILE: console/src/pages/Settings/Environments/useEnvVars.ts function useEnvVars (line 5) | function useEnvVars() { FILE: console/src/pages/Settings/Models/components/ModelManageModal.tsx constant POLL_INTERVAL_MS (line 29) | const POLL_INTERVAL_MS = 3000; type ModelManageModalProps (line 31) | interface ModelManageModalProps { function formatFileSize (line 38) | function formatFileSize(bytes: number): string { function ModelManageModal (line 45) | function ModelManageModal({ FILE: console/src/pages/Settings/Models/components/cards/LocalProviderCard.tsx type LocalProviderCardProps (line 9) | interface LocalProviderCardProps { function LocalProviderCard (line 17) | function LocalProviderCard({ FILE: console/src/pages/Settings/Models/components/cards/ProviderCard.tsx type ProviderCardProps (line 5) | interface ProviderCardProps { function ProviderCard (line 14) | function ProviderCard({ FILE: console/src/pages/Settings/Models/components/cards/RemoteProviderCard.tsx type RemoteProviderCardProps (line 15) | interface RemoteProviderCardProps { function RemoteProviderCard (line 24) | function RemoteProviderCard({ FILE: console/src/pages/Settings/Models/components/modals/CustomProviderModal.tsx type CustomProviderModalProps (line 6) | interface CustomProviderModalProps { function CustomProviderModal (line 12) | function CustomProviderModal({ FILE: console/src/pages/Settings/Models/components/modals/LocalModelManageModal.tsx constant POLL_INTERVAL_MS (line 27) | const POLL_INTERVAL_MS = 3000; type LocalModelManageModalProps (line 29) | interface LocalModelManageModalProps { function formatFileSize (line 36) | function formatFileSize(bytes: number): string { function LocalModelManageModal (line 43) | function LocalModelManageModal({ FILE: console/src/pages/Settings/Models/components/modals/ModelManageModal.tsx type ModelManageModalProps (line 6) | interface ModelManageModalProps { function ModelManageModal (line 13) | function ModelManageModal({ FILE: console/src/pages/Settings/Models/components/modals/OllamaModelManageModal.tsx constant POLL_INTERVAL_MS (line 20) | const POLL_INTERVAL_MS = 3000; type OllamaModelManageModalProps (line 22) | interface OllamaModelManageModalProps { function formatFileSize (line 29) | function formatFileSize(bytes: number): string { function OllamaModelManageModal (line 36) | function OllamaModelManageModal({ FILE: console/src/pages/Settings/Models/components/modals/ProviderConfigModal.tsx type ProviderConfigFormValues (line 17) | interface ProviderConfigFormValues type JsonCodeEditorProps (line 22) | interface JsonCodeEditorProps { function highlightJson (line 29) | function highlightJson(text: string): ReactNode[] { function JsonCodeEditor (line 103) | function JsonCodeEditor({ type ProviderConfigModalProps (line 244) | interface ProviderConfigModalProps { function ProviderConfigModal (line 263) | function ProviderConfigModal({ FILE: console/src/pages/Settings/Models/components/modals/RemoteModelManageModal.tsx type RemoteModelManageModalProps (line 22) | interface RemoteModelManageModalProps { function RemoteModelManageModal (line 29) | function RemoteModelManageModal({ FILE: console/src/pages/Settings/Models/components/sections/LoadingState.tsx type LoadingStateProps (line 5) | interface LoadingStateProps { function LoadingState (line 12) | function LoadingState({ FILE: console/src/pages/Settings/Models/components/sections/ModelsSection.tsx type ModelsSectionProps (line 9) | interface ModelsSectionProps { function ModelsSection (line 30) | function ModelsSection({ FILE: console/src/pages/Settings/Models/components/sections/PageHeader.tsx type PageHeaderProps (line 3) | interface PageHeaderProps { function PageHeader (line 9) | function PageHeader({ title, description, className }: PageHeaderProps) { FILE: console/src/pages/Settings/Models/index.tsx function ModelsPage (line 19) | function ModelsPage() { FILE: console/src/pages/Settings/Models/useProviders.ts function useProviders (line 6) | function useProviders() { FILE: console/src/pages/Settings/Security/components/PageHeader.tsx type PageHeaderProps (line 4) | interface PageHeaderProps { function PageHeader (line 8) | function PageHeader({ className }: PageHeaderProps) { FILE: console/src/pages/Settings/Security/components/PreviewModal.tsx constant SEVERITY_COLORS (line 5) | const SEVERITY_COLORS: Record = { type PreviewModalProps (line 13) | interface PreviewModalProps { function PreviewModal (line 18) | function PreviewModal({ rule, onClose }: PreviewModalProps) { FILE: console/src/pages/Settings/Security/components/RuleModal.tsx constant SEVERITY_OPTIONS (line 6) | const SEVERITY_OPTIONS = ["CRITICAL", "HIGH", "MEDIUM", "LOW", "INFO"]; constant CATEGORY_OPTIONS (line 7) | const CATEGORY_OPTIONS = [ constant BUILTIN_TOOLS (line 17) | const BUILTIN_TOOLS = [ type RuleModalProps (line 32) | interface RuleModalProps { function RuleModal (line 41) | function RuleModal({ FILE: console/src/pages/Settings/Security/components/RuleTable.tsx constant SEVERITY_COLORS (line 8) | const SEVERITY_COLORS: Record = { type RuleTableProps (line 16) | interface RuleTableProps { function RuleTable (line 25) | function RuleTable({ FILE: console/src/pages/Settings/Security/components/SkillScannerSection.tsx function FindingsModal (line 28) | function FindingsModal({ function SkillScannerSection (line 84) | function SkillScannerSection() { FILE: console/src/pages/Settings/Security/index.tsx constant BUILTIN_TOOLS (line 28) | const BUILTIN_TOOLS = [ function SecurityPage (line 43) | function SecurityPage() { FILE: console/src/pages/Settings/Security/useSkillScanner.ts function useSkillScanner (line 9) | function useSkillScanner() { FILE: console/src/pages/Settings/Security/useToolGuard.ts type MergedRule (line 8) | interface MergedRule extends ToolGuardRule { function useToolGuard (line 13) | function useToolGuard() { FILE: console/src/pages/Settings/TokenUsage/components/EmptyState.tsx type EmptyStateProps (line 3) | interface EmptyStateProps { function EmptyState (line 8) | function EmptyState({ message, className }: EmptyStateProps) { FILE: console/src/pages/Settings/TokenUsage/components/LoadingState.tsx type LoadingStateProps (line 5) | interface LoadingStateProps { function LoadingState (line 12) | function LoadingState({ FILE: console/src/pages/Settings/TokenUsage/components/PageHeader.tsx type PageHeaderProps (line 3) | interface PageHeaderProps { function PageHeader (line 9) | function PageHeader({ title, description, className }: PageHeaderProps) { FILE: console/src/pages/Settings/TokenUsage/index.tsx type ByModelRow (line 16) | type ByModelRow = TokenUsageStats & { key: string }; type ByDateRow (line 17) | type ByDateRow = TokenUsageStats & { key: string; date: string }; function TokenUsagePage (line 19) | function TokenUsagePage() { FILE: console/src/pages/Settings/VoiceTranscription/index.tsx type TranscriptionProvider (line 8) | interface TranscriptionProvider { type LocalWhisperStatus (line 14) | interface LocalWhisperStatus { function VoiceTranscriptionPage (line 20) | function VoiceTranscriptionPage() { FILE: console/src/stores/agentStore.ts type AgentStore (line 5) | interface AgentStore { FILE: console/src/utils/formatNumber.ts function formatCompact (line 5) | function formatCompact(n: number): string { FILE: console/src/vite-env.d.ts type PyWebViewAPI (line 8) | interface PyWebViewAPI { type Window (line 13) | interface Window { FILE: scripts/pack/build_common.py function _conda_exe (line 35) | def _conda_exe() -> str: function _run (line 43) | def _run( function _pick_wheel (line 55) | def _pick_wheel(wheel_arg: str | None) -> Path: function main (line 76) | def main() -> int: FILE: scripts/run_tests.py class Colors (line 33) | class Colors: function print_info (line 43) | def print_info(message: str) -> None: function print_success (line 48) | def print_success(message: str) -> None: function print_error (line 53) | def print_error(message: str) -> None: function print_warning (line 58) | def print_warning(message: str) -> None: function check_pytest (line 63) | def check_pytest() -> bool: function run_unit_tests (line 76) | def run_unit_tests( function run_integrated_tests (line 123) | def run_integrated_tests( function run_pytest (line 148) | def run_pytest( function main (line 175) | def main() -> int: FILE: src/copaw/agents/__init__.py function __getattr__ (line 24) | def __getattr__(name: str): FILE: src/copaw/agents/command_handler.py class ConversationCommandHandlerMixin (line 23) | class ConversationCommandHandlerMixin: method is_conversation_command (line 45) | def is_conversation_command(self, query: str | None) -> bool: class CommandHandler (line 59) | class CommandHandler(ConversationCommandHandlerMixin): method __init__ (line 62) | def __init__( method _get_agent_config (line 82) | def _get_agent_config(self): method is_command (line 90) | def is_command(self, query: str | None) -> bool: method _make_system_msg (line 94) | async def _make_system_msg(self, text: str) -> Msg: method _has_memory_manager (line 109) | def _has_memory_manager(self) -> bool: method _process_compact (line 113) | async def _process_compact( method _process_new (line 147) | async def _process_new(self, messages: list[Msg], _args: str = "") -> ... method _process_clear (line 174) | async def _process_clear( method _process_compact_str (line 188) | async def _process_compact_str( method _process_history (line 205) | async def _process_history( method _process_await_summary (line 232) | async def _process_await_summary( method _process_message (line 260) | async def _process_message( method _process_dump_history (line 328) | async def _process_dump_history( method _process_load_history (line 384) | async def _process_load_history( method handle_conversation_command (line 460) | async def handle_conversation_command(self, query: str) -> Msg: method handle_command (line 486) | async def handle_command(self, query: str) -> Msg: FILE: src/copaw/agents/hooks/bootstrap.py class BootstrapHook (line 20) | class BootstrapHook: method __init__ (line 28) | def __init__( method __call__ (line 42) | async def __call__( FILE: src/copaw/agents/hooks/memory_compaction.py class MemoryCompactionHook (line 28) | class MemoryCompactionHook: method __init__ (line 36) | def __init__(self, memory_manager: "MemoryManager"): method _print_status_message (line 45) | async def _print_status_message( method __call__ (line 62) | async def __call__( FILE: src/copaw/agents/memory/agent_md_manager.py class AgentMdManager (line 8) | class AgentMdManager: method __init__ (line 12) | def __init__(self, working_dir: str | Path): method list_working_mds (line 19) | def list_working_mds(self) -> list[dict]: method read_working_md (line 49) | def read_working_md(self, md_name: str) -> str: method write_working_md (line 64) | def write_working_md(self, md_name: str, content: str): method list_memory_mds (line 72) | def list_memory_mds(self) -> list[dict]: method read_memory_md (line 102) | def read_memory_md(self, md_name: str) -> str: method write_memory_md (line 117) | def write_memory_md(self, md_name: str, content: str): FILE: src/copaw/agents/memory/memory_manager.py class ReMeLight (line 36) | class ReMeLight: # type: ignore method start (line 39) | async def start(self) -> None: class MemoryManager (line 43) | class MemoryManager(ReMeLight): method __init__ (line 53) | def __init__( method mask_key (line 141) | def mask_key(key: str) -> str: method get_embedding_config (line 149) | def get_embedding_config(self) -> dict: method prepare_model_formatter (line 169) | def prepare_model_formatter(self) -> None: method restart_embedding_model (line 188) | async def restart_embedding_model(self): method compact_memory (line 198) | async def compact_memory( method summary_memory (line 230) | async def summary_memory(self, messages: list[Msg], **_kwargs) -> str: method memory_search (line 259) | async def memory_search( method get_in_memory_memory (line 295) | def get_in_memory_memory(self, **_kwargs): FILE: src/copaw/agents/model_factory.py function _file_url_to_path (line 40) | def _file_url_to_path(url: str) -> str: function _get_formatter_for_chat_model (line 64) | def _get_formatter_for_chat_model( function _create_file_block_support_formatter (line 82) | def _create_file_block_support_formatter( function _strip_top_level_message_name (line 266) | def _strip_top_level_message_name( function create_model_and_formatter (line 280) | def create_model_and_formatter( function _create_formatter_instance (line 352) | def _create_formatter_instance( FILE: src/copaw/agents/prompt.py class PromptConfig (line 23) | class PromptConfig: class PromptBuilder (line 35) | class PromptBuilder: method __init__ (line 44) | def __init__( method _load_file (line 63) | def _load_file(self, filename: str) -> None: method _process_heartbeat_section (line 115) | def _process_heartbeat_section(self, content: str) -> str: method build (line 142) | def build(self) -> str: function build_system_prompt_from_working_dir (line 177) | def build_system_prompt_from_working_dir( function build_bootstrap_guidance (line 260) | def build_bootstrap_guidance( FILE: src/copaw/agents/react_agent.py class CoPawAgent (line 63) | class CoPawAgent(ToolGuardMixin, ReActAgent): method __init__ (line 83) | def __init__( method _create_toolkit (line 166) | def _create_toolkit( method _register_skills (line 230) | def _register_skills(self, toolkit: Toolkit) -> None: method _build_sys_prompt (line 257) | def _build_sys_prompt(self) -> str: method _setup_memory_manager (line 288) | def _setup_memory_manager( method _register_hooks (line 323) | def _register_hooks(self) -> None: method rebuild_sys_prompt (line 353) | def rebuild_sys_prompt(self) -> None: method register_mcp_clients (line 369) | async def register_mcp_clients( method _recover_mcp_client (line 434) | async def _recover_mcp_client(self, client: Any) -> Any | None: method _reuse_shared_client_reference (line 452) | def _reuse_shared_client_reference( method _should_propagate_cancelled_error (line 465) | def _should_propagate_cancelled_error(error: BaseException) -> bool: method _reconnect_mcp_client (line 484) | async def _reconnect_mcp_client( method _rebuild_mcp_client (line 513) | def _rebuild_mcp_client(client: Any) -> Any | None: method _reasoning (line 558) | async def _reasoning( method _summarizing (line 587) | async def _summarizing(self) -> Msg: method print (line 623) | async def print( method _strip_tool_use_from_msg (line 670) | def _strip_tool_use_from_msg(msg: Msg) -> Msg: method _is_bad_request_or_media_error (line 703) | def _is_bad_request_or_media_error(exc: Exception) -> bool: method _strip_media_blocks_from_memory (line 730) | def _strip_media_blocks_from_memory(self) -> int: method reply (line 786) | async def reply( method interrupt (line 825) | async def interrupt(self, msg: Msg | list[Msg] | None = None) -> None: FILE: src/copaw/agents/routing_chat_model.py class RoutingDecision (line 24) | class RoutingDecision: class RoutingPolicy (line 29) | class RoutingPolicy: method __init__ (line 32) | def __init__(self, cfg: AgentsLLMRoutingConfig): method decide (line 35) | def decide( class RoutingEndpoint (line 57) | class RoutingEndpoint: class RoutingChatModel (line 65) | class RoutingChatModel(ChatModelBase): method __init__ (line 68) | def __init__( method __call__ (line 84) | async def __call__( FILE: src/copaw/agents/schema.py class FileBlock (line 11) | class FileBlock(TypedDict, total=False): FILE: src/copaw/agents/skills/docx/scripts/accept_changes.py function accept_changes (line 37) | def accept_changes( function _setup_libreoffice_macro (line 93) | def _setup_libreoffice_macro() -> bool: FILE: src/copaw/agents/skills/docx/scripts/comment.py function _generate_hex_id (line 68) | def _generate_hex_id() -> str: function _encode_smart_quotes (line 80) | def _encode_smart_quotes(text: str) -> str: function _append_xml (line 86) | def _append_xml(xml_path: Path, root_tag: str, content: str) -> None: function _find_para_id (line 98) | def _find_para_id(comments_path: Path, comment_id: int) -> str | None: function _get_next_rid (line 108) | def _get_next_rid(rels_path: Path) -> int: function _has_relationship (line 121) | def _has_relationship(rels_path: Path, target: str) -> bool: function _has_content_type (line 129) | def _has_content_type(ct_path: Path, part_name: str) -> bool: function _ensure_comment_relationships (line 137) | def _ensure_comment_relationships(unpacked_dir: Path) -> None: function _ensure_comment_content_types (line 179) | def _ensure_comment_content_types(unpacked_dir: Path) -> None: function add_comment (line 218) | def add_comment( FILE: src/copaw/agents/skills/docx/scripts/office/helpers/merge_runs.py function merge_runs (line 16) | def merge_runs(input_dir: str) -> tuple[int, str]: function _find_elements (line 44) | def _find_elements(root, tag: str) -> list: function _get_child (line 59) | def _get_child(parent, tag: str): function _get_children (line 68) | def _get_children(parent, tag: str) -> list: function _is_adjacent (line 78) | def _is_adjacent(elem1, elem2) -> bool: function _remove_elements (line 93) | def _remove_elements(root, tag: str): function _strip_run_rsid_attrs (line 99) | def _strip_run_rsid_attrs(root): function _merge_runs_in (line 108) | def _merge_runs_in(container) -> int: function _first_child_run (line 128) | def _first_child_run(container): function _next_element_sibling (line 135) | def _next_element_sibling(node): function _next_sibling_run (line 144) | def _next_sibling_run(node): function _is_run (line 154) | def _is_run(node) -> bool: function _can_merge (line 159) | def _can_merge(run1, run2) -> bool: function _merge_run_content (line 170) | def _merge_run_content(target, source): function _consolidate_text (line 178) | def _consolidate_text(run): FILE: src/copaw/agents/skills/docx/scripts/office/helpers/simplify_redlines.py function simplify_redlines (line 22) | def simplify_redlines(input_dir: str) -> tuple[int, str]: function _merge_tracked_changes_in (line 47) | def _merge_tracked_changes_in(container, tag: str) -> int: function _is_element (line 75) | def _is_element(node, tag: str) -> bool: function _get_author (line 80) | def _get_author(elem) -> str: function _can_merge_tracked (line 89) | def _can_merge_tracked(elem1, elem2) -> bool: function _merge_tracked_content (line 104) | def _merge_tracked_content(target, source): function _find_elements (line 111) | def _find_elements(root, tag: str) -> list: function get_tracked_change_authors (line 126) | def get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]: function _get_authors_from_docx (line 149) | def _get_authors_from_docx(docx_path: Path) -> dict[str, int]: function infer_author (line 172) | def infer_author(modified_dir: Path, original_docx: Path, default: str =... FILE: src/copaw/agents/skills/docx/scripts/office/pack.py function pack (line 24) | def pack( function _run_validation (line 69) | def _run_validation( function _condense_xml (line 108) | def _condense_xml(xml_file: Path) -> None: FILE: src/copaw/agents/skills/docx/scripts/office/soffice.py function get_soffice_cmd (line 26) | def get_soffice_cmd() -> str: function get_soffice_env (line 56) | def get_soffice_env() -> dict: function run_soffice (line 69) | def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess: function _needs_shim (line 78) | def _needs_shim() -> bool: function _ensure_shim (line 90) | def _ensure_shim() -> Path: FILE: src/copaw/agents/skills/docx/scripts/office/unpack.py function unpack (line 34) | def unpack( function _pretty_print_xml (line 82) | def _pretty_print_xml(xml_file: Path) -> None: function _escape_smart_quotes (line 91) | def _escape_smart_quotes(xml_file: Path) -> None: FILE: src/copaw/agents/skills/docx/scripts/office/validate.py function main (line 25) | def main(): FILE: src/copaw/agents/skills/docx/scripts/office/validators/base.py class BaseSchemaValidator (line 12) | class BaseSchemaValidator: method __init__ (line 94) | def __init__(self, unpacked_dir, original_file=None, verbose=False): method validate (line 109) | def validate(self): method repair (line 112) | def repair(self) -> int: method repair_whitespace_preservation (line 115) | def repair_whitespace_preservation(self) -> int: method validate_xml (line 143) | def validate_xml(self): method validate_namespaces (line 170) | def validate_namespaces(self): method validate_unique_ids (line 199) | def validate_unique_ids(self): method validate_file_references (line 289) | def validate_file_references(self): method validate_all_relationship_ids (line 385) | def validate_all_relationship_ids(self): method _get_expected_relationship_type (line 469) | def _get_expected_relationship_type(self, element_name): method validate_content_types (line 492) | def validate_content_types(self): method validate_file_against_xsd (line 598) | def validate_file_against_xsd(self, xml_file, verbose=False): method validate_against_xsd (line 636) | def validate_against_xsd(self): method _get_schema_path (line 685) | def _get_schema_path(self, xml_file): method _clean_ignorable_namespaces (line 703) | def _clean_ignorable_namespaces(self, xml_doc): method _remove_ignorable_elements (line 723) | def _remove_ignorable_elements(self, root): method _preprocess_for_mc_ignorable (line 742) | def _preprocess_for_mc_ignorable(self, xml_doc): method _validate_single_file_xsd (line 750) | def _validate_single_file_xsd(self, xml_file, base_path): method _get_original_file_errors (line 787) | def _get_original_file_errors(self, xml_file): method _remove_template_tags_from_text_nodes (line 814) | def _remove_template_tags_from_text_nodes(self, xml_doc): FILE: src/copaw/agents/skills/docx/scripts/office/validators/docx.py class DOCXSchemaValidator (line 17) | class DOCXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_whitespace_preservation (line 67) | def validate_whitespace_preservation(self): method validate_deletions (line 113) | def validate_deletions(self): method count_paragraphs_in_unpacked (line 164) | def count_paragraphs_in_unpacked(self): method count_paragraphs_in_original (line 180) | def count_paragraphs_in_original(self): method validate_insertions (line 203) | def validate_insertions(self): method compare_paragraph_counts (line 244) | def compare_paragraph_counts(self): method _parse_id_value (line 252) | def _parse_id_value(self, val: str, base: int = 16) -> int: method validate_id_constraints (line 255) | def validate_id_constraints(self): method validate_comment_markers (line 299) | def validate_comment_markers(self): method repair (line 387) | def repair(self) -> int: method repair_durableId (line 392) | def repair_durableId(self) -> int: FILE: src/copaw/agents/skills/docx/scripts/office/validators/pptx.py class PPTXSchemaValidator (line 10) | class PPTXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_uuid_ids (line 62) | def validate_uuid_ids(self): method _looks_like_uuid (line 100) | def _looks_like_uuid(self, value): method validate_slide_layout_ids (line 104) | def validate_slide_layout_ids(self): method validate_no_duplicate_slide_layouts (line 172) | def validate_no_duplicate_slide_layouts(self): method validate_notes_slide_references (line 210) | def validate_notes_slide_references(self): FILE: src/copaw/agents/skills/docx/scripts/office/validators/redlining.py class RedliningValidator (line 11) | class RedliningValidator: method __init__ (line 13) | def __init__(self, unpacked_dir, original_docx, verbose=False, author=... method repair (line 22) | def repair(self) -> int: method validate (line 25) | def validate(self): method _generate_detailed_diff (line 104) | def _generate_detailed_diff(self, original_text, modified_text): method _get_git_word_diff (line 127) | def _get_git_word_diff(self, original_text, modified_text): method _remove_author_tracked_changes (line 198) | def _remove_author_tracked_changes(self, root): method _extract_text_content (line 229) | def _extract_text_content(self, root): FILE: src/copaw/agents/skills/pdf/scripts/check_bounding_boxes.py class RectAndField (line 9) | class RectAndField: function get_bounding_box_messages (line 15) | def get_bounding_box_messages(fields_json_stream) -> list[str]: FILE: src/copaw/agents/skills/pdf/scripts/convert_pdf_to_images.py function convert (line 9) | def convert(pdf_path, output_dir, max_dim=1000): FILE: src/copaw/agents/skills/pdf/scripts/create_validation_image.py function create_validation_image (line 9) | def create_validation_image(page_number, fields_json_path, input_path, o... FILE: src/copaw/agents/skills/pdf/scripts/extract_form_field_info.py function get_full_annotation_field_id (line 9) | def get_full_annotation_field_id(annotation): function make_field_dict (line 19) | def make_field_dict(field, field_id): function get_field_info (line 47) | def get_field_info(reader: PdfReader): function write_field_info (line 110) | def write_field_info(pdf_path: str, json_output_path: str): FILE: src/copaw/agents/skills/pdf/scripts/extract_form_structure.py function extract_form_structure (line 20) | def extract_form_structure(pdf_path): function main (line 91) | def main(): FILE: src/copaw/agents/skills/pdf/scripts/fill_fillable_fields.py function fill_pdf_fields (line 11) | def fill_pdf_fields(input_pdf_path: str, fields_json_path: str, output_p... function validation_error_for_field_value (line 55) | def validation_error_for_field_value(field_info, field_value): function monkeypatch_pydpf_method (line 74) | def monkeypatch_pydpf_method(): FILE: src/copaw/agents/skills/pdf/scripts/fill_pdf_form_with_annotations.py function transform_from_image_coords (line 10) | def transform_from_image_coords(bbox, image_width, image_height, pdf_wid... function transform_from_pdf_coords (line 23) | def transform_from_pdf_coords(bbox, pdf_height): function fill_pdf_form (line 33) | def fill_pdf_form(input_pdf_path, fields_json_path, output_pdf_path): FILE: src/copaw/agents/skills/pptx/scripts/add_slide.py function get_next_slide_number (line 27) | def get_next_slide_number(slides_dir: Path) -> int: function create_slide_from_layout (line 33) | def create_slide_from_layout(unpacked_dir: Path, layout_file: str) -> None: function duplicate_slide (line 90) | def duplicate_slide(unpacked_dir: Path, source: str) -> None: function _add_to_content_types (line 130) | def _add_to_content_types(unpacked_dir: Path, dest: str) -> None: function _add_to_presentation_rels (line 141) | def _add_to_presentation_rels(unpacked_dir: Path, dest: str) -> str: function _get_next_slide_id (line 158) | def _get_next_slide_id(unpacked_dir: Path) -> int: function parse_source (line 165) | def parse_source(source: str) -> tuple[str, str | None]: FILE: src/copaw/agents/skills/pptx/scripts/clean.py function get_slides_in_sldidlst (line 27) | def get_slides_in_sldidlst(unpacked_dir: Path) -> set[str]: function remove_orphaned_slides (line 49) | def remove_orphaned_slides(unpacked_dir: Path) -> list[str]: function remove_trash_directory (line 91) | def remove_trash_directory(unpacked_dir: Path) -> list[str]: function get_slide_referenced_files (line 106) | def get_slide_referenced_files(unpacked_dir: Path) -> set: function remove_orphaned_rels_files (line 128) | def remove_orphaned_rels_files(unpacked_dir: Path) -> list[str]: function get_referenced_files (line 153) | def get_referenced_files(unpacked_dir: Path) -> set: function remove_orphaned_files (line 171) | def remove_orphaned_files(unpacked_dir: Path, referenced: set) -> list[s... function update_content_types (line 221) | def update_content_types(unpacked_dir: Path, removed_files: list[str]) -... function clean_unused_files (line 241) | def clean_unused_files(unpacked_dir: Path) -> list[str]: FILE: src/copaw/agents/skills/pptx/scripts/office/helpers/merge_runs.py function merge_runs (line 16) | def merge_runs(input_dir: str) -> tuple[int, str]: function _find_elements (line 44) | def _find_elements(root, tag: str) -> list: function _get_child (line 59) | def _get_child(parent, tag: str): function _get_children (line 68) | def _get_children(parent, tag: str) -> list: function _is_adjacent (line 78) | def _is_adjacent(elem1, elem2) -> bool: function _remove_elements (line 93) | def _remove_elements(root, tag: str): function _strip_run_rsid_attrs (line 99) | def _strip_run_rsid_attrs(root): function _merge_runs_in (line 108) | def _merge_runs_in(container) -> int: function _first_child_run (line 128) | def _first_child_run(container): function _next_element_sibling (line 135) | def _next_element_sibling(node): function _next_sibling_run (line 144) | def _next_sibling_run(node): function _is_run (line 154) | def _is_run(node) -> bool: function _can_merge (line 159) | def _can_merge(run1, run2) -> bool: function _merge_run_content (line 170) | def _merge_run_content(target, source): function _consolidate_text (line 178) | def _consolidate_text(run): FILE: src/copaw/agents/skills/pptx/scripts/office/helpers/simplify_redlines.py function simplify_redlines (line 22) | def simplify_redlines(input_dir: str) -> tuple[int, str]: function _merge_tracked_changes_in (line 47) | def _merge_tracked_changes_in(container, tag: str) -> int: function _is_element (line 75) | def _is_element(node, tag: str) -> bool: function _get_author (line 80) | def _get_author(elem) -> str: function _can_merge_tracked (line 89) | def _can_merge_tracked(elem1, elem2) -> bool: function _merge_tracked_content (line 104) | def _merge_tracked_content(target, source): function _find_elements (line 111) | def _find_elements(root, tag: str) -> list: function get_tracked_change_authors (line 126) | def get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]: function _get_authors_from_docx (line 149) | def _get_authors_from_docx(docx_path: Path) -> dict[str, int]: function infer_author (line 172) | def infer_author(modified_dir: Path, original_docx: Path, default: str =... FILE: src/copaw/agents/skills/pptx/scripts/office/pack.py function pack (line 24) | def pack( function _run_validation (line 69) | def _run_validation( function _condense_xml (line 108) | def _condense_xml(xml_file: Path) -> None: FILE: src/copaw/agents/skills/pptx/scripts/office/soffice.py function get_soffice_cmd (line 26) | def get_soffice_cmd() -> str: function get_soffice_env (line 55) | def get_soffice_env() -> dict: function run_soffice (line 67) | def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess: function _needs_shim (line 76) | def _needs_shim() -> bool: function _ensure_shim (line 88) | def _ensure_shim() -> Path: FILE: src/copaw/agents/skills/pptx/scripts/office/unpack.py function unpack (line 34) | def unpack( function _pretty_print_xml (line 82) | def _pretty_print_xml(xml_file: Path) -> None: function _escape_smart_quotes (line 91) | def _escape_smart_quotes(xml_file: Path) -> None: FILE: src/copaw/agents/skills/pptx/scripts/office/validate.py function main (line 25) | def main(): FILE: src/copaw/agents/skills/pptx/scripts/office/validators/base.py class BaseSchemaValidator (line 12) | class BaseSchemaValidator: method __init__ (line 94) | def __init__(self, unpacked_dir, original_file=None, verbose=False): method validate (line 109) | def validate(self): method repair (line 112) | def repair(self) -> int: method repair_whitespace_preservation (line 115) | def repair_whitespace_preservation(self) -> int: method validate_xml (line 143) | def validate_xml(self): method validate_namespaces (line 170) | def validate_namespaces(self): method validate_unique_ids (line 199) | def validate_unique_ids(self): method validate_file_references (line 289) | def validate_file_references(self): method validate_all_relationship_ids (line 385) | def validate_all_relationship_ids(self): method _get_expected_relationship_type (line 469) | def _get_expected_relationship_type(self, element_name): method validate_content_types (line 492) | def validate_content_types(self): method validate_file_against_xsd (line 598) | def validate_file_against_xsd(self, xml_file, verbose=False): method validate_against_xsd (line 636) | def validate_against_xsd(self): method _get_schema_path (line 685) | def _get_schema_path(self, xml_file): method _clean_ignorable_namespaces (line 703) | def _clean_ignorable_namespaces(self, xml_doc): method _remove_ignorable_elements (line 723) | def _remove_ignorable_elements(self, root): method _preprocess_for_mc_ignorable (line 742) | def _preprocess_for_mc_ignorable(self, xml_doc): method _validate_single_file_xsd (line 750) | def _validate_single_file_xsd(self, xml_file, base_path): method _get_original_file_errors (line 787) | def _get_original_file_errors(self, xml_file): method _remove_template_tags_from_text_nodes (line 814) | def _remove_template_tags_from_text_nodes(self, xml_doc): FILE: src/copaw/agents/skills/pptx/scripts/office/validators/docx.py class DOCXSchemaValidator (line 17) | class DOCXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_whitespace_preservation (line 67) | def validate_whitespace_preservation(self): method validate_deletions (line 113) | def validate_deletions(self): method count_paragraphs_in_unpacked (line 164) | def count_paragraphs_in_unpacked(self): method count_paragraphs_in_original (line 180) | def count_paragraphs_in_original(self): method validate_insertions (line 203) | def validate_insertions(self): method compare_paragraph_counts (line 244) | def compare_paragraph_counts(self): method _parse_id_value (line 252) | def _parse_id_value(self, val: str, base: int = 16) -> int: method validate_id_constraints (line 255) | def validate_id_constraints(self): method validate_comment_markers (line 299) | def validate_comment_markers(self): method repair (line 387) | def repair(self) -> int: method repair_durableId (line 392) | def repair_durableId(self) -> int: FILE: src/copaw/agents/skills/pptx/scripts/office/validators/pptx.py class PPTXSchemaValidator (line 10) | class PPTXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_uuid_ids (line 62) | def validate_uuid_ids(self): method _looks_like_uuid (line 100) | def _looks_like_uuid(self, value): method validate_slide_layout_ids (line 104) | def validate_slide_layout_ids(self): method validate_no_duplicate_slide_layouts (line 172) | def validate_no_duplicate_slide_layouts(self): method validate_notes_slide_references (line 210) | def validate_notes_slide_references(self): FILE: src/copaw/agents/skills/pptx/scripts/office/validators/redlining.py class RedliningValidator (line 11) | class RedliningValidator: method __init__ (line 13) | def __init__(self, unpacked_dir, original_docx, verbose=False, author=... method repair (line 22) | def repair(self) -> int: method validate (line 25) | def validate(self): method _generate_detailed_diff (line 104) | def _generate_detailed_diff(self, original_text, modified_text): method _get_git_word_diff (line 127) | def _get_git_word_diff(self, original_text, modified_text): method _remove_author_tracked_changes (line 198) | def _remove_author_tracked_changes(self, root): method _extract_text_content (line 229) | def _extract_text_content(self, root): FILE: src/copaw/agents/skills/pptx/scripts/thumbnail.py function main (line 40) | def main(): function get_slide_info (line 95) | def get_slide_info(pptx_path: Path) -> list[dict]: function build_slide_list (line 121) | def build_slide_list( function create_hidden_placeholder (line 149) | def create_hidden_placeholder(size: tuple[int, int]) -> Image.Image: function convert_to_images (line 158) | def convert_to_images(pptx_path: Path, temp_dir: Path) -> list[Path]: function create_grids (line 213) | def create_grids( function create_grid (line 242) | def create_grid( FILE: src/copaw/agents/skills/xlsx/scripts/office/helpers/merge_runs.py function merge_runs (line 16) | def merge_runs(input_dir: str) -> tuple[int, str]: function _find_elements (line 44) | def _find_elements(root, tag: str) -> list: function _get_child (line 59) | def _get_child(parent, tag: str): function _get_children (line 68) | def _get_children(parent, tag: str) -> list: function _is_adjacent (line 78) | def _is_adjacent(elem1, elem2) -> bool: function _remove_elements (line 93) | def _remove_elements(root, tag: str): function _strip_run_rsid_attrs (line 99) | def _strip_run_rsid_attrs(root): function _merge_runs_in (line 108) | def _merge_runs_in(container) -> int: function _first_child_run (line 128) | def _first_child_run(container): function _next_element_sibling (line 135) | def _next_element_sibling(node): function _next_sibling_run (line 144) | def _next_sibling_run(node): function _is_run (line 154) | def _is_run(node) -> bool: function _can_merge (line 159) | def _can_merge(run1, run2) -> bool: function _merge_run_content (line 170) | def _merge_run_content(target, source): function _consolidate_text (line 178) | def _consolidate_text(run): FILE: src/copaw/agents/skills/xlsx/scripts/office/helpers/simplify_redlines.py function simplify_redlines (line 22) | def simplify_redlines(input_dir: str) -> tuple[int, str]: function _merge_tracked_changes_in (line 47) | def _merge_tracked_changes_in(container, tag: str) -> int: function _is_element (line 75) | def _is_element(node, tag: str) -> bool: function _get_author (line 80) | def _get_author(elem) -> str: function _can_merge_tracked (line 89) | def _can_merge_tracked(elem1, elem2) -> bool: function _merge_tracked_content (line 104) | def _merge_tracked_content(target, source): function _find_elements (line 111) | def _find_elements(root, tag: str) -> list: function get_tracked_change_authors (line 126) | def get_tracked_change_authors(doc_xml_path: Path) -> dict[str, int]: function _get_authors_from_docx (line 149) | def _get_authors_from_docx(docx_path: Path) -> dict[str, int]: function infer_author (line 172) | def infer_author(modified_dir: Path, original_docx: Path, default: str =... FILE: src/copaw/agents/skills/xlsx/scripts/office/pack.py function pack (line 24) | def pack( function _run_validation (line 69) | def _run_validation( function _condense_xml (line 108) | def _condense_xml(xml_file: Path) -> None: FILE: src/copaw/agents/skills/xlsx/scripts/office/soffice.py function get_soffice_cmd (line 26) | def get_soffice_cmd() -> str: function get_soffice_env (line 55) | def get_soffice_env() -> dict: function run_soffice (line 67) | def run_soffice(args: list[str], **kwargs) -> subprocess.CompletedProcess: function _needs_shim (line 76) | def _needs_shim() -> bool: function _ensure_shim (line 88) | def _ensure_shim() -> Path: FILE: src/copaw/agents/skills/xlsx/scripts/office/unpack.py function unpack (line 34) | def unpack( function _pretty_print_xml (line 82) | def _pretty_print_xml(xml_file: Path) -> None: function _escape_smart_quotes (line 91) | def _escape_smart_quotes(xml_file: Path) -> None: FILE: src/copaw/agents/skills/xlsx/scripts/office/validate.py function main (line 25) | def main(): FILE: src/copaw/agents/skills/xlsx/scripts/office/validators/base.py class BaseSchemaValidator (line 12) | class BaseSchemaValidator: method __init__ (line 94) | def __init__(self, unpacked_dir, original_file=None, verbose=False): method validate (line 109) | def validate(self): method repair (line 112) | def repair(self) -> int: method repair_whitespace_preservation (line 115) | def repair_whitespace_preservation(self) -> int: method validate_xml (line 143) | def validate_xml(self): method validate_namespaces (line 170) | def validate_namespaces(self): method validate_unique_ids (line 199) | def validate_unique_ids(self): method validate_file_references (line 289) | def validate_file_references(self): method validate_all_relationship_ids (line 385) | def validate_all_relationship_ids(self): method _get_expected_relationship_type (line 469) | def _get_expected_relationship_type(self, element_name): method validate_content_types (line 492) | def validate_content_types(self): method validate_file_against_xsd (line 598) | def validate_file_against_xsd(self, xml_file, verbose=False): method validate_against_xsd (line 636) | def validate_against_xsd(self): method _get_schema_path (line 685) | def _get_schema_path(self, xml_file): method _clean_ignorable_namespaces (line 703) | def _clean_ignorable_namespaces(self, xml_doc): method _remove_ignorable_elements (line 723) | def _remove_ignorable_elements(self, root): method _preprocess_for_mc_ignorable (line 742) | def _preprocess_for_mc_ignorable(self, xml_doc): method _validate_single_file_xsd (line 750) | def _validate_single_file_xsd(self, xml_file, base_path): method _get_original_file_errors (line 787) | def _get_original_file_errors(self, xml_file): method _remove_template_tags_from_text_nodes (line 814) | def _remove_template_tags_from_text_nodes(self, xml_doc): FILE: src/copaw/agents/skills/xlsx/scripts/office/validators/docx.py class DOCXSchemaValidator (line 17) | class DOCXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_whitespace_preservation (line 67) | def validate_whitespace_preservation(self): method validate_deletions (line 113) | def validate_deletions(self): method count_paragraphs_in_unpacked (line 164) | def count_paragraphs_in_unpacked(self): method count_paragraphs_in_original (line 180) | def count_paragraphs_in_original(self): method validate_insertions (line 203) | def validate_insertions(self): method compare_paragraph_counts (line 244) | def compare_paragraph_counts(self): method _parse_id_value (line 252) | def _parse_id_value(self, val: str, base: int = 16) -> int: method validate_id_constraints (line 255) | def validate_id_constraints(self): method validate_comment_markers (line 299) | def validate_comment_markers(self): method repair (line 387) | def repair(self) -> int: method repair_durableId (line 392) | def repair_durableId(self) -> int: FILE: src/copaw/agents/skills/xlsx/scripts/office/validators/pptx.py class PPTXSchemaValidator (line 10) | class PPTXSchemaValidator(BaseSchemaValidator): method validate (line 25) | def validate(self): method validate_uuid_ids (line 62) | def validate_uuid_ids(self): method _looks_like_uuid (line 100) | def _looks_like_uuid(self, value): method validate_slide_layout_ids (line 104) | def validate_slide_layout_ids(self): method validate_no_duplicate_slide_layouts (line 172) | def validate_no_duplicate_slide_layouts(self): method validate_notes_slide_references (line 210) | def validate_notes_slide_references(self): FILE: src/copaw/agents/skills/xlsx/scripts/office/validators/redlining.py class RedliningValidator (line 11) | class RedliningValidator: method __init__ (line 13) | def __init__(self, unpacked_dir, original_docx, verbose=False, author=... method repair (line 22) | def repair(self) -> int: method validate (line 25) | def validate(self): method _generate_detailed_diff (line 104) | def _generate_detailed_diff(self, original_text, modified_text): method _get_git_word_diff (line 127) | def _get_git_word_diff(self, original_text, modified_text): method _remove_author_tracked_changes (line 198) | def _remove_author_tracked_changes(self, root): method _extract_text_content (line 229) | def _extract_text_content(self, root): FILE: src/copaw/agents/skills/xlsx/scripts/recalc.py function has_gtimeout (line 33) | def has_gtimeout(): function _get_macro_dir (line 43) | def _get_macro_dir() -> str: function setup_libreoffice_macro (line 54) | def setup_libreoffice_macro(): function recalc (line 80) | def recalc(filename, timeout=30): function main (line 189) | def main(): FILE: src/copaw/agents/skills_hub.py class HubSkillResult (line 35) | class HubSkillResult: class HubInstallResult (line 44) | class HubInstallResult: class SkillImportCancelled (line 50) | class SkillImportCancelled(RuntimeError): function _hub_http_timeout (line 70) | def _hub_http_timeout() -> float: function _hub_http_retries (line 78) | def _hub_http_retries() -> int: function _hub_http_backoff_base (line 86) | def _hub_http_backoff_base() -> float: function _hub_http_backoff_cap (line 94) | def _hub_http_backoff_cap() -> float: function _compute_backoff_seconds (line 102) | def _compute_backoff_seconds(attempt: int) -> float: function _ensure_not_cancelled (line 108) | def _ensure_not_cancelled() -> None: function _with_cancel_checker (line 123) | def _with_cancel_checker(checker: Any | None): function _hub_base_url (line 131) | def _hub_base_url() -> str: function _hub_search_path (line 135) | def _hub_search_path() -> str: function _hub_version_path (line 142) | def _hub_version_path() -> str: function _hub_detail_path (line 149) | def _hub_detail_path() -> str: function _hub_file_path (line 156) | def _hub_file_path() -> str: function _join_url (line 163) | def _join_url(base: str, path: str) -> str: function _build_request (line 167) | def _build_request(full_url: str, accept: str) -> Request: function _read_response_bytes (line 183) | def _read_response_bytes( function _http_fetch (line 226) | def _http_fetch( function _http_get (line 338) | def _http_get( function _http_bytes_get (line 350) | def _http_bytes_get( function _http_json_get (line 364) | def _http_json_get(url: str, params: dict[str, Any] | None = None) -> Any: function _http_text_get (line 369) | def _http_text_get(url: str, params: dict[str, Any] | None = None) -> str: function _norm_search_items (line 377) | def _norm_search_items(data: Any) -> list[dict[str, Any]]: function _safe_path_parts (line 390) | def _safe_path_parts(path: str) -> list[str] | None: function _tree_insert (line 402) | def _tree_insert( function _files_to_tree (line 417) | def _files_to_tree( function _sanitize_tree (line 435) | def _sanitize_tree(tree: Any) -> dict[str, Any]: function _bundle_has_content (line 451) | def _bundle_has_content(payload: Any) -> bool: function _extract_version_hint (line 467) | def _extract_version_hint( function _hydrate_clawhub_payload (line 489) | def _hydrate_clawhub_payload( function _normalize_bundle (line 574) | def _normalize_bundle( function _safe_fallback_name (line 636) | def _safe_fallback_name(raw: str) -> str: function _extract_error_message_from_payload (line 641) | def _extract_error_message_from_payload(payload: bytes) -> str: function _lobehub_http_error_message (line 657) | def _lobehub_http_error_message(error: HTTPError) -> str: function _is_probably_text_blob (line 670) | def _is_probably_text_blob(payload: bytes) -> bool: function _should_keep_lobehub_file (line 682) | def _should_keep_lobehub_file(parts: list[str]) -> bool: function _sanitize_skill_dir_name (line 692) | def _sanitize_skill_dir_name(name: str) -> str: function _is_http_url (line 706) | def _is_http_url(text: str) -> bool: function _extract_clawhub_slug_from_url (line 711) | def _extract_clawhub_slug_from_url(url: str) -> str: function _extract_skills_sh_spec (line 723) | def _extract_skills_sh_spec(url: str) -> tuple[str, str, str] | None: function _extract_skillsmp_slug (line 737) | def _extract_skillsmp_slug(url: str) -> str: function _extract_lobehub_identifier (line 752) | def _extract_lobehub_identifier(url: str) -> str: function _extract_modelscope_skill_spec (line 772) | def _extract_modelscope_skill_spec( function _extract_github_spec (line 804) | def _extract_github_spec( function _github_repo_exists (line 831) | def _github_repo_exists(owner: str, repo: str) -> bool: function _extract_skillsmp_spec (line 842) | def _extract_skillsmp_spec( function _resolve_clawhub_slug (line 882) | def _resolve_clawhub_slug(bundle_url: str) -> str: function _github_api_url (line 889) | def _github_api_url(owner: str, repo: str, suffix: str) -> str: function _github_encode_path (line 895) | def _github_encode_path(path: str) -> str: function _github_get_default_branch (line 902) | def _github_get_default_branch(owner: str, repo: str) -> str: function _normalize_skill_key (line 911) | def _normalize_skill_key(text: str) -> str: function _github_list_skill_md_roots (line 915) | def _github_list_skill_md_roots( function _github_get_content_entry (line 955) | def _github_get_content_entry( function _github_get_dir_entries (line 969) | def _github_get_dir_entries( function _github_read_file (line 984) | def _github_read_file(entry: dict[str, Any]) -> str: function _join_repo_path (line 1003) | def _join_repo_path(root: str, leaf: str) -> str: function _relative_from_root (line 1009) | def _relative_from_root(full_path: str, root: str) -> str: function _github_collect_tree_files (line 1018) | def _github_collect_tree_files( function _fetch_bundle_from_skills_sh_url (line 1057) | def _fetch_bundle_from_skills_sh_url( function _fetch_bundle_from_repo_and_skill_hint (line 1159) | def _fetch_bundle_from_repo_and_skill_hint( function _fetch_bundle_from_github_url (line 1262) | def _fetch_bundle_from_github_url( function _fetch_bundle_from_skillsmp_url (line 1295) | def _fetch_bundle_from_skillsmp_url( function _lobehub_download_url (line 1311) | def _lobehub_download_url(identifier: str) -> str: function _lobehub_zip_to_bundle (line 1315) | def _lobehub_zip_to_bundle(identifier: str, payload: bytes) -> dict[str,... function _fetch_bundle_from_modelscope_url (line 1370) | def _fetch_bundle_from_modelscope_url( function _fetch_bundle_from_lobehub_url (line 1450) | def _fetch_bundle_from_lobehub_url( function _fetch_bundle_from_clawhub_slug (line 1479) | def _fetch_bundle_from_clawhub_slug( function search_hub_skills (line 1513) | def search_hub_skills(query: str, limit: int = 20) -> list[HubSkillResult]: function _resolve_bundle_from_url (line 1539) | def _resolve_bundle_from_url( function install_skill_from_hub (line 1567) | def install_skill_from_hub( FILE: src/copaw/agents/skills_manager.py function _dedupe_skills_by_name (line 20) | def _dedupe_skills_by_name(skills: list["SkillInfo"]) -> list["SkillInfo"]: class SkillInfo (line 28) | class SkillInfo(BaseModel): function get_builtin_skills_dir (line 63) | def get_builtin_skills_dir() -> Path: function get_customized_skills_dir (line 68) | def get_customized_skills_dir(workspace_dir: Path) -> Path: function get_active_skills_dir (line 73) | def get_active_skills_dir(workspace_dir: Path) -> Path: function get_working_skills_dir (line 78) | def get_working_skills_dir(workspace_dir: Path) -> Path: function _build_directory_tree (line 87) | def _build_directory_tree(directory: Path) -> dict[str, Any]: function _collect_skills_from_dir (line 124) | def _collect_skills_from_dir(directory: Path) -> dict[str, Path]: function _get_builtin_skill_version (line 142) | def _get_builtin_skill_version(skill_dir: Path) -> Version | None: function _replace_skill_dir (line 164) | def _replace_skill_dir(source: Path, target: Path) -> None: function _skill_md_differs (line 171) | def _skill_md_differs(dir_a: Path, dir_b: Path) -> bool: function sync_skills_to_working_dir (line 183) | def sync_skills_to_working_dir( function sync_skills_from_active_to_customized (line 263) | def sync_skills_from_active_to_customized( function list_available_skills (line 344) | def list_available_skills(workspace_dir: Path) -> list[str]: function ensure_skills_initialized (line 366) | def ensure_skills_initialized(workspace_dir: Path) -> None: function _read_skills_from_dir (line 394) | def _read_skills_from_dir( function _create_files_from_tree (line 473) | def _create_files_from_tree( function _is_hidden (line 524) | def _is_hidden(name: str) -> bool: function _extract_and_validate_zip (line 529) | def _extract_and_validate_zip(data: bytes, tmp_dir: Path) -> None: function _resolve_skill_name (line 552) | def _resolve_skill_name(skill_dir: Path) -> str: function _find_skill_dirs (line 569) | def _find_skill_dirs(root: Path) -> list[tuple[Path, str]]: function _import_skill_dir (line 580) | def _import_skill_dir( class SkillService (line 627) | class SkillService: method __init__ (line 635) | def __init__(self, workspace_dir: Path): method get_customized_skill_dir (line 644) | def get_customized_skill_dir(self, name: str) -> Path | None: method list_all_skills (line 649) | def list_all_skills(self) -> list[SkillInfo]: method list_available_skills (line 687) | def list_available_skills(self) -> list[SkillInfo]: method create_skill (line 699) | def create_skill( method disable_skill (line 861) | def disable_skill(self, name: str) -> bool: method enable_skill (line 893) | def enable_skill(self, name: str, force: bool = False) -> bool: method delete_skill (line 942) | def delete_skill(self, name: str) -> bool: method sync_from_active_to_customized (line 982) | def sync_from_active_to_customized( method import_from_zip (line 1000) | def import_from_zip( method load_skill_file (line 1087) | def load_skill_file( # pylint: disable=too-many-return-statements FILE: src/copaw/agents/tool_guard_mixin.py class ToolGuardMixin (line 24) | class ToolGuardMixin: method _init_tool_guard (line 36) | def _init_tool_guard(self) -> None: method _ensure_tool_guard (line 45) | def _ensure_tool_guard(self) -> None: method _should_require_approval (line 53) | def _should_require_approval(self) -> bool: method _last_tool_response_is_denied (line 57) | def _last_tool_response_is_denied(self) -> bool: method _cleanup_tool_guard_denied_messages (line 64) | async def _cleanup_tool_guard_denied_messages( method _acting (line 103) | async def _acting(self, tool_call) -> dict | None: # noqa: C901 method _acting_auto_denied (line 187) | async def _acting_auto_denied( method _acting_with_approval (line 237) | async def _acting_with_approval( method _reasoning (line 315) | async def _reasoning( FILE: src/copaw/agents/tools/browser_control.py function _get_executor (line 46) | def _get_executor() -> futures.ThreadPoolExecutor: function _run_sync (line 55) | async def _run_sync(func, *args, **kwargs): function _run_sync (line 65) | async def _run_sync(func, *args, **kwargs): function _touch_activity (line 97) | def _touch_activity() -> None: function _is_browser_running (line 102) | def _is_browser_running() -> bool: function _reset_browser_state (line 109) | def _reset_browser_state() -> None: function _idle_watchdog (line 132) | async def _idle_watchdog(idle_seconds: float = _BROWSER_IDLE_TIMEOUT) ->... function _atexit_cleanup (line 156) | def _atexit_cleanup() -> None: function _tool_response (line 177) | def _tool_response(text: str) -> ToolResponse: function _chromium_launch_args (line 184) | def _chromium_launch_args() -> list[str]: function _chromium_executable_path (line 191) | def _chromium_executable_path() -> str | None: function _use_webkit_fallback (line 196) | def _use_webkit_fallback() -> bool: function _ensure_playwright_async (line 204) | def _ensure_playwright_async(): function _ensure_playwright_sync (line 219) | def _ensure_playwright_sync(): function _sync_browser_launch (line 234) | def _sync_browser_launch(headless: bool): function _sync_browser_close (line 272) | def _sync_browser_close(): function _parse_json_param (line 286) | def _parse_json_param(value: str, default: Any = None): function browser_use (line 301) | async def browser_use( # pylint: disable=R0911,R0912 function _get_page (line 610) | def _get_page(page_id: str): function _get_refs (line 615) | def _get_refs(page_id: str) -> dict[str, dict]: function _get_root (line 620) | def _get_root(page, _page_id: str, frame_selector: str = ""): function _get_locator_by_ref (line 627) | def _get_locator_by_ref( function _attach_page_listeners (line 648) | def _attach_page_listeners(page, page_id: str) -> None: function _next_page_id (line 689) | def _next_page_id() -> str: function _attach_context_listeners (line 696) | def _attach_context_listeners(context) -> None: function _ensure_browser (line 718) | async def _ensure_browser() -> bool: # pylint: disable=too-many-branches function _start_idle_watchdog (line 797) | def _start_idle_watchdog() -> None: function _cancel_idle_watchdog (line 805) | def _cancel_idle_watchdog() -> None: function _action_start (line 814) | async def _action_start( function _action_stop (line 917) | async def _action_stop() -> ToolResponse: function _action_open (line 974) | async def _action_open(url: str, page_id: str) -> ToolResponse: function _action_navigate (line 1046) | async def _action_navigate(url: str, page_id: str) -> ToolResponse: function _action_screenshot (line 1096) | async def _action_screenshot( function _action_click (line 1207) | async def _action_click( # pylint: disable=too-many-branches function _action_type (line 1341) | async def _action_type( function _action_eval (line 1449) | async def _action_eval(page_id: str, code: str) -> ToolResponse: function _action_pdf (line 1505) | async def _action_pdf(page_id: str, path: str) -> ToolResponse: function _action_close (line 1538) | async def _action_close(page_id: str) -> ToolResponse: function _action_snapshot (line 1583) | async def _action_snapshot( function _action_navigate_back (line 1645) | async def _action_navigate_back(page_id: str) -> ToolResponse: function _action_evaluate (line 1677) | async def _action_evaluate( function _action_resize (line 1763) | async def _action_resize( function _action_console_messages (line 1810) | async def _action_console_messages( function _action_handle_dialog (line 1858) | async def _action_handle_dialog( function _action_file_upload (line 1916) | async def _action_file_upload(page_id: str, paths_json: str) -> ToolResp... function _action_fill_form (line 1976) | async def _action_fill_form(page_id: str, fields_json: str) -> ToolRespo... function _run_playwright_install (line 2062) | def _run_playwright_install() -> None: function _action_install (line 2073) | async def _action_install() -> ToolResponse: function _action_press_key (line 2137) | async def _action_press_key(page_id: str, key: str) -> ToolResponse: function _action_network_requests (line 2178) | async def _action_network_requests( function _action_run_code (line 2224) | async def _action_run_code(page_id: str, code: str) -> ToolResponse: function _action_drag (line 2281) | async def _action_drag( function _action_hover (line 2366) | async def _action_hover( function _action_select_option (line 2427) | async def _action_select_option( function _action_tabs (line 2497) | async def _action_tabs( # pylint: disable=too-many-return-statements function _action_wait_for (line 2613) | async def _action_wait_for( FILE: src/copaw/agents/tools/browser_snapshot.py function _get_indent_level (line 68) | def _get_indent_level(line: str) -> int: function _create_tracker (line 73) | def _create_tracker() -> dict[str, Any]: function _remove_nth_from_non_duplicates (line 101) | def _remove_nth_from_non_duplicates( function _compact_tree (line 112) | def _compact_tree(tree: str) -> str: function _process_line (line 135) | def _process_line( # pylint: disable=too-many-return-statements function build_role_snapshot_from_aria (line 185) | def build_role_snapshot_from_aria( FILE: src/copaw/agents/tools/desktop_screenshot.py function _tool_error (line 15) | def _tool_error(msg: str) -> ToolResponse: function _tool_ok (line 30) | def _tool_ok(path: str, message: str) -> ToolResponse: function _capture_mss (line 49) | def _capture_mss(path: str) -> ToolResponse: function _capture_macos_screencapture (line 69) | def _capture_macos_screencapture( function desktop_screenshot (line 101) | async def desktop_screenshot( FILE: src/copaw/agents/tools/file_io.py function _resolve_file_path (line 16) | def _resolve_file_path(file_path: str) -> str: function read_file (line 35) | async def read_file( # pylint: disable=too-many-return-statements function write_file (line 165) | async def write_file( function edit_file (line 213) | async def edit_file( function append_file (line 305) | async def append_file( FILE: src/copaw/agents/tools/file_search.py function _is_text_file (line 71) | def _is_text_file(path: Path) -> bool: function grep_search (line 83) | async def grep_search( # pylint: disable=too-many-branches function glob_search (line 221) | async def glob_search( function _relative_display (line 314) | def _relative_display(target: Path, root: Path) -> str: FILE: src/copaw/agents/tools/get_current_time.py function get_current_time (line 16) | async def get_current_time() -> ToolResponse: function set_user_timezone (line 48) | async def set_user_timezone(timezone_name: str) -> ToolResponse: FILE: src/copaw/agents/tools/get_token_usage.py function get_token_usage (line 12) | async def get_token_usage( FILE: src/copaw/agents/tools/memory_search.py function create_memory_search_tool (line 7) | def create_memory_search_tool(memory_manager): FILE: src/copaw/agents/tools/send_file.py function _auto_as_type (line 19) | def _auto_as_type(mt: str) -> str: function send_file_to_user (line 29) | async def send_file_to_user( FILE: src/copaw/agents/tools/shell.py function _kill_process_tree_win32 (line 21) | def _kill_process_tree_win32(pid: int) -> None: function _execute_subprocess_sync (line 38) | def _execute_subprocess_sync( function execute_shell_command (line 126) | async def execute_shell_command( function smart_decode (line 280) | def smart_decode(data: bytes) -> str: FILE: src/copaw/agents/tools/utils.py function truncate_output (line 10) | def truncate_output( function _truncate_line_by_bytes (line 79) | def _truncate_line_by_bytes(line: str, max_bytes: int) -> str: function _truncate_line_by_bytes_tail (line 106) | def _truncate_line_by_bytes_tail(line: str, max_bytes: int) -> str: function truncate_file_output (line 133) | def truncate_file_output( function truncate_shell_output (line 184) | def truncate_shell_output(text: str) -> str: function read_file_safe (line 226) | def read_file_safe(file_path: str) -> str: FILE: src/copaw/agents/tools/view_image.py function view_image (line 24) | async def view_image(image_path: str) -> ToolResponse: FILE: src/copaw/agents/utils/audio_transcription.py function _get_local_whisper_model (line 27) | def _get_local_whisper_model(): function _url_for_provider (line 46) | def _url_for_provider(provider) -> Optional[Tuple[str, str]]: function _get_manager (line 71) | def _get_manager(): function list_transcription_providers (line 87) | def list_transcription_providers() -> List[dict]: function get_configured_transcription_provider_id (line 115) | def get_configured_transcription_provider_id() -> str: function check_local_whisper_available (line 122) | def check_local_whisper_available() -> dict: function _transcribe_local_whisper (line 155) | async def _transcribe_local_whisper(file_path: str) -> Optional[str]: function _get_configured_provider_creds (line 203) | def _get_configured_provider_creds() -> Optional[Tuple[str, str]]: function _transcribe_whisper_api (line 236) | async def _transcribe_whisper_api(file_path: str) -> Optional[str]: function transcribe_audio (line 295) | async def transcribe_audio(file_path: str) -> Optional[str]: FILE: src/copaw/agents/utils/copaw_token_counter.py class CopawTokenCounter (line 20) | class CopawTokenCounter(HuggingFaceTokenCounter): method __init__ (line 35) | def __init__( method count (line 99) | async def count( method estimate_tokens (line 138) | def estimate_tokens(self, text: str) -> int: function get_copaw_token_counter (line 160) | def get_copaw_token_counter( FILE: src/copaw/agents/utils/file_handling.py function _resolve_local_path (line 23) | def _resolve_local_path( function _download_remote_to_path (line 56) | def _download_remote_to_path(url: str, local_file_path: Path) -> None: function _guess_suffix_from_url_headers (line 96) | def _guess_suffix_from_url_headers(url: str) -> Optional[str]: function _guess_suffix_from_file_content (line 130) | def _guess_suffix_from_file_content(path: Path) -> Optional[str]: function download_file_from_base64 (line 146) | async def download_file_from_base64( function download_file_from_url (line 184) | async def download_file_from_url( FILE: src/copaw/agents/utils/message_processing.py function _process_single_file_block (line 25) | async def _process_single_file_block( function _extract_source_and_filename (line 76) | def _extract_source_and_filename(block: dict, block_type: str): function _media_type_from_path (line 95) | def _media_type_from_path(path: str) -> str: function _convert_audio_to_wav (line 114) | def _convert_audio_to_wav(src_path: str) -> Optional[str]: function _update_block_with_local_path (line 181) | def _update_block_with_local_path( function _handle_download_failure (line 206) | def _handle_download_failure(block_type: str) -> Optional[dict]: function _process_audio_block (line 217) | async def _process_audio_block( function _process_single_block (line 292) | async def _process_single_block( function process_file_and_media_blocks_in_message (line 374) | async def process_file_and_media_blocks_in_message(msg) -> None: function is_first_user_interaction (line 419) | def is_first_user_interaction(messages: list) -> bool: function prepend_to_message_content (line 442) | def prepend_to_message_content(msg, guidance: str) -> None: FILE: src/copaw/agents/utils/setup_utils.py function copy_md_files (line 14) | def copy_md_files( FILE: src/copaw/agents/utils/tool_message_utils.py function extract_tool_ids (line 13) | def extract_tool_ids(msg) -> tuple[set[str], set[str]]: function check_valid_messages (line 35) | def check_valid_messages(messages: list) -> bool: function _reorder_tool_results (line 56) | def _reorder_tool_results(msgs: list) -> list: function _remove_unpaired_tool_messages (line 104) | def _remove_unpaired_tool_messages(msgs: list) -> list: function _dedup_tool_blocks (line 150) | def _dedup_tool_blocks(msgs: list) -> list: function _remove_invalid_tool_blocks (line 179) | def _remove_invalid_tool_blocks(msgs: list) -> list: function _repair_empty_tool_inputs (line 250) | def _repair_empty_tool_inputs( function _sanitize_tool_messages (line 322) | def _sanitize_tool_messages(msgs: list) -> list: function _truncate_text (line 359) | def _truncate_text(text: str, max_length: int) -> str: FILE: src/copaw/app/_app.py class DynamicMultiAgentRunner (line 49) | class DynamicMultiAgentRunner: method __init__ (line 56) | def __init__(self): method set_multi_agent_manager (line 60) | def set_multi_agent_manager(self, manager): method _get_workspace_runner (line 64) | async def _get_workspace_runner(self, request): method stream_query (line 95) | async def stream_query(self, request, *args, **kwargs): method query_handler (line 119) | async def query_handler(self, request, *args, **kwargs): method __aenter__ (line 127) | async def __aenter__(self): method __aexit__ (line 133) | async def __aexit__(self, exc_type, exc_val, exc_tb): function lifespan (line 149) | async def lifespan( function _resolve_console_static_dir (line 270) | def _resolve_console_static_dir() -> str: function read_root (line 307) | def read_root(): function get_version (line 322) | def get_version(): function _serve_console_index (line 349) | def _serve_console_index(): function _console_logo (line 356) | def _console_logo(): function _console_dark_logo (line 363) | def _console_dark_logo(): function _console_icon (line 370) | def _console_icon(): function _console_dark_icon (line 377) | def _console_dark_icon(): function _console_spa_alias (line 394) | def _console_spa_alias(full_path: str = ""): function _console_spa (line 401) | def _console_spa(full_path: str): FILE: src/copaw/app/agent_config_watcher.py function _heartbeat_hash (line 28) | def _heartbeat_hash(hb: Optional[HeartbeatConfig]) -> int: class AgentConfigWatcher (line 35) | class AgentConfigWatcher: method __init__ (line 42) | def __init__( method start (line 74) | async def start(self) -> None: method stop (line 86) | async def stop(self) -> None: method _snapshot (line 101) | def _snapshot(self) -> None: method _channels_hash (line 134) | def _channels_hash(channels: ChannelConfig) -> int: method _channel_dump (line 139) | def _channel_dump(ch: Any) -> Any: method _reload_one_channel (line 149) | async def _reload_one_channel( method _apply_channel_changes (line 178) | async def _apply_channel_changes(self, agent_config: Any) -> None: method _apply_heartbeat_change (line 218) | async def _apply_heartbeat_change(self, agent_config: Any) -> None: method _poll_loop (line 240) | async def _poll_loop(self) -> None: method _check (line 252) | async def _check(self) -> None: FILE: src/copaw/app/agent_context.py function get_agent_for_request (line 22) | async def get_agent_for_request( function get_active_agent_id (line 86) | def get_active_agent_id() -> str: function set_current_agent_id (line 99) | def set_current_agent_id(agent_id: str) -> None: function get_current_agent_id (line 108) | def get_current_agent_id() -> str: FILE: src/copaw/app/approvals/service.py class PendingApproval (line 36) | class PendingApproval: class ApprovalService (line 58) | class ApprovalService: method __init__ (line 66) | def __init__(self) -> None: method set_channel_manager (line 72) | def set_channel_manager(self, channel_manager: Any) -> None: method create_pending (line 80) | async def create_pending( method resolve_request (line 116) | async def resolve_request( method get_request (line 137) | async def get_request(self, request_id: str) -> PendingApproval | None: method get_pending_by_session (line 144) | async def get_pending_by_session( method consume_approval (line 158) | async def consume_approval( method _gc_pending_locked (line 209) | def _gc_pending_locked(self) -> None: method _gc_completed_locked (line 243) | def _gc_completed_locked(self) -> None: function get_approval_service (line 276) | def get_approval_service() -> ApprovalService: FILE: src/copaw/app/auth.py function _chmod_best_effort (line 64) | def _chmod_best_effort(path, mode: int) -> None: function _prepare_secret_parent (line 71) | def _prepare_secret_parent(path) -> None: function _hash_password (line 81) | def _hash_password( function verify_password (line 92) | def verify_password(password: str, stored_hash: str, salt: str) -> bool: function _get_jwt_secret (line 103) | def _get_jwt_secret() -> str: function create_token (line 114) | def create_token(username: str) -> str: function verify_token (line 135) | def verify_token(token: str) -> Optional[str]: function _load_auth_data (line 166) | def _load_auth_data() -> dict: function _save_auth_data (line 183) | def _save_auth_data(data: dict) -> None: function is_auth_enabled (line 191) | def is_auth_enabled() -> bool: function has_registered_users (line 203) | def has_registered_users() -> bool: function register_user (line 214) | def register_user(username: str, password: str) -> Optional[str]: function auto_register_from_env (line 241) | def auto_register_from_env() -> None: function authenticate (line 278) | def authenticate(username: str, password: str) -> Optional[str]: class AuthMiddleware (line 302) | class AuthMiddleware(BaseHTTPMiddleware): method dispatch (line 305) | async def dispatch( method _should_skip_auth (line 336) | def _should_skip_auth(request: Request) -> bool: method _extract_token (line 360) | def _extract_token(request: Request) -> Optional[str]: FILE: src/copaw/app/channels/__init__.py function __getattr__ (line 7) | def __getattr__(name: str): FILE: src/copaw/app/channels/base.py class BaseChannel (line 69) | class BaseChannel(ABC): method __init__ (line 79) | def __init__( method _is_native_payload (line 126) | def _is_native_payload(self, payload: Any) -> bool: method get_debounce_key (line 130) | def get_debounce_key(self, payload: Any) -> str: method merge_native_items (line 145) | def merge_native_items(self, items: List[Any]) -> Any: method merge_requests (line 176) | def merge_requests(self, requests: List[Any]) -> Any: method _on_debounce_buffer_append (line 208) | def _on_debounce_buffer_append( method _content_has_text (line 222) | def _content_has_text(self, contents: List[Any]) -> bool: method _content_has_audio (line 240) | def _content_has_audio(self, contents: List[Any]) -> bool: method _apply_no_text_debounce (line 247) | def _apply_no_text_debounce( method _check_allowlist (line 281) | def _check_allowlist( method _check_group_mention (line 305) | def _check_group_mention( method set_enqueue (line 317) | def set_enqueue(self, cb: EnqueueCallback) -> None: method from_env (line 322) | def from_env( method from_config (line 330) | def from_config( method resolve_session_id (line 341) | def resolve_session_id( method build_agent_request_from_user_content (line 353) | def build_agent_request_from_user_content( method build_agent_request_from_native (line 388) | def build_agent_request_from_native( method _payload_to_request (line 404) | def _payload_to_request(self, payload: Any) -> "AgentRequest": method get_to_handle_from_request (line 416) | def get_to_handle_from_request(self, request: "AgentRequest") -> str: method get_on_reply_sent_args (line 423) | def get_on_reply_sent_args( method refresh_webhook_or_token (line 437) | async def refresh_webhook_or_token(self) -> None: method consume_one (line 443) | async def consume_one(self, payload: Any) -> None: method _consume_one_request (line 481) | async def _consume_one_request(self, payload: Any) -> None: method _run_process_loop (line 541) | async def _run_process_loop( method _get_response_error_message (line 584) | def _get_response_error_message(self, last_response: Any) -> Optional[... method _before_consume_process (line 605) | async def _before_consume_process(self, request: "AgentRequest") -> None: method on_event_message_completed (line 611) | async def on_event_message_completed( method on_event_response (line 624) | async def on_event_response( method _on_consume_error (line 631) | async def _on_consume_error( method send_response (line 648) | async def send_response( method _message_to_content_parts (line 663) | def _message_to_content_parts( method send_message_content (line 674) | async def send_message_content( method send_content_parts (line 700) | async def send_content_parts( method send_media (line 753) | async def send_media( method _response_to_text (line 766) | def _response_to_text(self, response: "AgentResponse") -> str: method clone (line 789) | def clone(self, config) -> "BaseChannel": method start (line 816) | async def start(self) -> None: method stop (line 819) | async def stop(self) -> None: method send (line 822) | async def send( method to_handle_from_target (line 833) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method send_event (line 842) | async def send_event( FILE: src/copaw/app/channels/console/channel.py function _ts (line 52) | def _ts() -> str: class ConsoleChannel (line 56) | class ConsoleChannel(BaseChannel): method __init__ (line 70) | def __init__( method media_dir (line 119) | def media_dir(self) -> Path: method from_env (line 124) | def from_env( method from_config (line 138) | def from_config( method resolve_session_id (line 174) | def resolve_session_id( method _resolve_console_upload_refs (line 187) | def _resolve_console_upload_refs( method build_agent_request_from_native (line 243) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method stream_one (line 266) | async def stream_one(self, payload: Any) -> AsyncGenerator[str, None]: method consume_one (line 355) | async def consume_one(self, payload: Any) -> None: method _print_parts (line 362) | def _print_parts( method _print_error (line 394) | def _print_error(self, err: str) -> None: method _parts_to_text (line 401) | def _parts_to_text( method send (line 424) | async def send( method send_content_parts (line 443) | async def send_content_parts( method start (line 461) | async def start(self) -> None: method stop (line 467) | async def stop(self) -> None: FILE: src/copaw/app/channels/dingtalk/ai_card.py class ActiveAICard (line 21) | class ActiveAICard: class AICardPendingStore (line 33) | class AICardPendingStore: method __init__ (line 36) | def __init__(self, path: Path): method path (line 40) | def path(self) -> Path: method load (line 43) | def load(self) -> List[dict]: method save (line 55) | def save(self, cards: Dict[str, ActiveAICard]) -> None: function is_group_conversation (line 82) | def is_group_conversation(conversation_id: str) -> bool: function thinking_or_tool_to_card_text (line 86) | def thinking_or_tool_to_card_text(text: str, title: str) -> str: function to_pending_record (line 99) | def to_pending_record(card: ActiveAICard) -> dict: FILE: src/copaw/app/channels/dingtalk/channel.py class DingTalkChannel (line 81) | class DingTalkChannel(BaseChannel): method __init__ (line 97) | def __init__( method from_env (line 183) | def from_env( method from_config (line 218) | def from_config( method resolve_session_id (line 257) | def resolve_session_id( method build_agent_request_from_native (line 269) | def build_agent_request_from_native( method to_handle_from_target (line 293) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method _route_from_handle (line 298) | def _route_from_handle(self, to_handle: str) -> dict: method _session_webhook_store_path (line 316) | def _session_webhook_store_path(self) -> Path: method _load_session_webhook_store_from_disk (line 326) | def _load_session_webhook_store_from_disk(self) -> None: method _save_session_webhook_store_to_disk (line 345) | def _save_session_webhook_store_to_disk(self) -> None: method _save_session_webhook (line 364) | async def _save_session_webhook( method _load_session_webhook (line 387) | async def _load_session_webhook(self, webhook_key: str) -> Optional[str]: method _try_accept_message (line 421) | def _try_accept_message(self, msg_id: str) -> bool: method _release_message_ids (line 442) | def _release_message_ids(self, msg_ids: List[str]) -> None: method _safe_set_future_result (line 457) | def _safe_set_future_result( method _reply_sync (line 469) | def _reply_sync(self, meta: Dict[str, Any], text: str) -> None: method _reply_sync_batch (line 488) | def _reply_sync_batch(self, meta: Dict[str, Any], text: str) -> None: method _ack_early (line 506) | def _ack_early(self, meta: Dict[str, Any], text: str) -> None: method _get_session_webhook (line 542) | def _get_session_webhook( method _parts_to_single_text (line 561) | def _parts_to_single_text( method _send_payload_via_session_webhook (line 596) | async def _send_payload_via_session_webhook( method _send_via_session_webhook (line 669) | async def _send_via_session_webhook( method _upload_media (line 694) | async def _upload_media( method _fetch_bytes_from_url (line 778) | async def _fetch_bytes_from_url(self, url: str) -> Optional[bytes]: method _get_session_webhook_for_send (line 822) | async def _get_session_webhook_for_send( method _map_upload_type (line 879) | def _map_upload_type(self, part: OutgoingContentPart) -> Optional[str]: method _send_media_part_via_webhook (line 897) | async def _send_media_part_via_webhook( method send_content_parts (line 1204) | async def send_content_parts( method merge_native_items (line 1312) | def merge_native_items(self, items: List[Any]) -> Any: method _on_debounce_buffer_append (line 1316) | def _on_debounce_buffer_append( method _run_process_loop (line 1335) | async def _run_process_loop( method _process_one_request (line 1412) | async def _process_one_request( method _merge_native (line 1646) | def _merge_native(self, items: list) -> dict: method _run_stream_forever (line 1701) | def _run_stream_forever(self) -> None: method _stream_loop (line 1716) | async def _stream_loop(self) -> None: method start (line 1769) | async def start(self) -> None: method stop (line 1810) | async def stop(self) -> None: method _ai_card_enabled (line 1851) | def _ai_card_enabled(self) -> bool: method _build_ai_card_initial_text (line 1858) | def _build_ai_card_initial_text(self) -> str: method _merge_ai_card_text (line 1861) | def _merge_ai_card_text(self, current: str, incoming: str) -> str: method _save_active_cards (line 1872) | async def _save_active_cards(self) -> None: method _mark_card_failed (line 1876) | async def _mark_card_failed(self, conversation_id: str) -> None: method _create_ai_card (line 1885) | async def _create_ai_card( method _stream_ai_card (line 2058) | async def _stream_ai_card( method _finish_ai_card (line 2157) | async def _finish_ai_card( method _recover_active_cards (line 2168) | async def _recover_active_cards(self) -> None: method send (line 2210) | async def send( method _get_access_token (line 2268) | async def _get_access_token(self) -> str: method _get_message_file_download_url (line 2308) | async def _get_message_file_download_url( method _download_media_to_local (line 2350) | async def _download_media_to_local( method _fetch_and_download_media (line 2413) | async def _fetch_and_download_media( method _guess_filename_and_ext (line 2436) | def _guess_filename_and_ext( method _is_public_http_url (line 2494) | def _is_public_http_url(self, s: Optional[str]) -> bool: FILE: src/copaw/app/channels/dingtalk/content_utils.py function dingtalk_content_from_type (line 33) | def dingtalk_content_from_type(mapped: str, url: str) -> Any: function parse_data_url (line 48) | def parse_data_url(data_url: str) -> tuple[bytes, Optional[str]]: function sender_from_chatbot_message (line 63) | def sender_from_chatbot_message(incoming_message: Any) -> tuple[str, bool]: function conversation_id_from_chatbot_message (line 89) | def conversation_id_from_chatbot_message(incoming_message: Any) -> str: function conversation_type_from_chatbot_message (line 99) | def conversation_type_from_chatbot_message(incoming_message: Any) -> str: function short_session_id_from_conversation_id (line 117) | def short_session_id_from_conversation_id(conversation_id: str) -> str: function session_param_from_webhook_url (line 125) | def session_param_from_webhook_url(url: str) -> Optional[str]: function get_type_mapping (line 139) | def get_type_mapping() -> dict: FILE: src/copaw/app/channels/dingtalk/handler.py class DingTalkChannelHandler (line 39) | class DingTalkChannelHandler(dingtalk_stream.ChatbotHandler): method __init__ (line 43) | def __init__( method _emit_native_threadsafe (line 58) | def _emit_native_threadsafe(self, native: dict) -> None: method _fetch_download_url_and_content (line 65) | def _fetch_download_url_and_content( method _extract_filename_hint (line 92) | def _extract_filename_hint(payload: Dict[str, Any]) -> Optional[str]: method _parse_rich_content (line 100) | def _parse_rich_content( method process (line 189) | async def process(self, callback: CallbackMessage) -> tuple[int, str]: FILE: src/copaw/app/channels/dingtalk/markdown.py function ensure_list_spacing (line 7) | def ensure_list_spacing(text: str) -> str: function dedent_code_blocks (line 44) | def dedent_code_blocks(text: str) -> str: function format_code_blocks (line 73) | def format_code_blocks(text: str, prefix: str = "·") -> str: function normalize_dingtalk_markdown (line 96) | def normalize_dingtalk_markdown( FILE: src/copaw/app/channels/dingtalk/utils.py function guess_suffix_from_file_content (line 23) | def guess_suffix_from_file_content(path: Path) -> Optional[str]: FILE: src/copaw/app/channels/discord_/channel.py class DiscordChannel (line 39) | class DiscordChannel(BaseChannel): method __init__ (line 44) | def __init__( method from_env (line 229) | def from_env( method from_config (line 259) | def from_config( method _resolve_target (line 286) | async def _resolve_target(self, to_handle, _meta): method _chunk_text (line 306) | def _chunk_text(text: str, max_len: int = 2000) -> list[str]: method send (line 369) | async def send( method send_content_parts (line 403) | async def send_content_parts( method send_media (line 432) | async def send_media( method _run (line 496) | async def _run(self) -> None: method start (line 501) | async def start(self) -> None: method stop (line 506) | async def stop(self) -> None: method resolve_session_id (line 518) | def resolve_session_id( method get_to_handle_from_request (line 534) | def get_to_handle_from_request(self, request: Any) -> str: method build_agent_request_from_native (line 540) | def build_agent_request_from_native(self, native_payload) -> Any: method to_handle_from_target (line 560) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method _route_from_handle (line 563) | def _route_from_handle(self, to_handle: str) -> dict: FILE: src/copaw/app/channels/feishu/channel.py function _declare_namespace_shim (line 71) | def _declare_namespace_shim(_name: str) -> None: class FeishuChannel (line 145) | class FeishuChannel(BaseChannel): method __init__ (line 156) | def __init__( method from_env (line 231) | def from_env( method from_config (line 262) | def from_config( method resolve_session_id (line 293) | def resolve_session_id( method build_agent_request_from_native (line 310) | def build_agent_request_from_native( method merge_native_items (line 348) | def merge_native_items(self, items: List[Any]) -> Any: method to_handle_from_target (line 369) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method _route_from_handle (line 375) | def _route_from_handle(self, to_handle: str) -> Dict[str, str]: method _get_tenant_access_token (line 398) | async def _get_tenant_access_token(self) -> str: method _fetch_bot_open_id (line 447) | async def _fetch_bot_open_id(self) -> Optional[str]: method _get_user_name_by_open_id (line 464) | async def _get_user_name_by_open_id(self, open_id: str) -> Optional[str]: method _emit_request_threadsafe (line 585) | def _emit_request_threadsafe(self, request: Any) -> None: method _on_message_sync (line 590) | def _on_message_sync(self, data: "P2ImMessageReceiveV1") -> None: method _on_message (line 605) | async def _on_message(self, data: "P2ImMessageReceiveV1") -> None: method _add_reaction (line 856) | async def _add_reaction( method _add_reaction_sync (line 878) | def _add_reaction_sync(self, message_id: str, emoji_type: str) -> None: method _download_image_resource (line 904) | async def _download_image_resource( method _download_file_resource (line 947) | async def _download_file_resource( method _receive_id_store_path (line 1015) | def _receive_id_store_path(self) -> Path: method _load_receive_id_store_from_disk (line 1026) | def _load_receive_id_store_from_disk(self) -> None: method _save_receive_id_store_to_disk (line 1055) | def _save_receive_id_store_to_disk(self) -> None: method _save_receive_id (line 1078) | async def _save_receive_id( method _load_receive_id (line 1102) | async def _load_receive_id( method _build_post_content (line 1115) | def _build_post_content( method _upload_image_sync (line 1135) | def _upload_image_sync(self, data: bytes, filename: str) -> Optional[s... method _upload_file (line 1175) | async def _upload_file(self, path_or_url: str) -> Optional[str]: method _fetch_bytes_from_url (line 1250) | async def _fetch_bytes_from_url(self, url: str) -> Optional[bytes]: method _send_message_sync (line 1266) | def _send_message_sync( method _send_text (line 1322) | async def _send_text( method _part_to_image_bytes (line 1365) | async def _part_to_image_bytes( method _send_image (line 1412) | async def _send_image( method _part_to_file_path_or_url (line 1457) | async def _part_to_file_path_or_url( method _send_file (line 1515) | async def _send_file( method _get_receive_for_send (line 1557) | async def _get_receive_for_send( method send_content_parts (line 1632) | async def send_content_parts( # type: ignore[override] method _run_process_loop (line 1736) | async def _run_process_loop( method send (line 1784) | async def send( method get_to_handle_from_request (line 1806) | def get_to_handle_from_request(self, request: Any) -> str: method get_on_reply_sent_args (line 1818) | def get_on_reply_sent_args( method _before_consume_process (line 1829) | async def _before_consume_process(self, request: Any) -> None: method _run_ws_forever (line 1841) | def _run_ws_forever(self) -> None: method start (line 1930) | async def start(self) -> None: method stop (line 1990) | async def stop(self) -> None: FILE: src/copaw/app/channels/feishu/utils.py function short_session_id_from_full_id (line 11) | def short_session_id_from_full_id(full_id: str) -> str: function sender_display_string (line 17) | def sender_display_string( function extract_json_key (line 28) | def extract_json_key(content: Optional[str], *keys: str) -> Optional[str]: function extract_post_text (line 43) | def extract_post_text(content: Optional[str]) -> Optional[str]: function _extract_post_keys (line 95) | def _extract_post_keys( function extract_post_image_keys (line 125) | def extract_post_image_keys(content: Optional[str]) -> list[str]: function extract_post_media_file_keys (line 130) | def extract_post_media_file_keys(content: Optional[str]) -> list[str]: function normalize_feishu_md (line 135) | def normalize_feishu_md(text: str) -> str: function _parse_md_table (line 146) | def _parse_md_table(table_lines: List[str]) -> Optional[Dict[str, Any]]: function _convert_md_headings_to_bold (line 229) | def _convert_md_headings_to_bold(text: str) -> str: function _build_elements (line 237) | def _build_elements(text: str) -> List[Dict[str, Any]]: function _split_elements (line 286) | def _split_elements( function build_interactive_content (line 316) | def build_interactive_content(text: str) -> str: function build_interactive_content_chunks (line 323) | def build_interactive_content_chunks(text: str) -> List[str]: FILE: src/copaw/app/channels/imessage/channel.py class IMessageChannel (line 38) | class IMessageChannel(BaseChannel): method __init__ (line 41) | def __init__( method from_env (line 81) | def from_env( method from_config (line 103) | def from_config( method _ensure_imsg (line 126) | def _ensure_imsg(self) -> str: method _send_sync (line 137) | def _send_sync( method _emit_request_threadsafe (line 169) | def _emit_request_threadsafe(self, request: Any) -> None: method _watcher_loop (line 174) | def _watcher_loop(self) -> None: method build_agent_request_from_native (line 248) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method _on_consume_error (line 265) | async def _on_consume_error( method start (line 274) | async def start(self) -> None: method stop (line 286) | async def stop(self) -> None: method send (line 294) | async def send( method send_content_parts (line 305) | async def send_content_parts( method _extract_url_and_filename (line 384) | def _extract_url_and_filename(self, part: OutgoingContentPart): method _get_file_extension (line 414) | def _get_file_extension( method _sanitize_filename (line 434) | def _sanitize_filename(self, filename: str) -> str: method _handle_local_file (line 465) | async def _handle_local_file(self, url: str) -> Optional[str]: method _handle_remote_url (line 483) | async def _handle_remote_url( method _handle_data_url (line 508) | async def _handle_data_url( method send_media (line 587) | async def send_media( FILE: src/copaw/app/channels/manager.py function _drain_same_key (line 42) | def _drain_same_key( function _process_batch (line 65) | async def _process_batch(ch: BaseChannel, batch: List[Any]) -> None: function _put_pending_merged (line 94) | def _put_pending_merged( class ChannelManager (line 114) | class ChannelManager: method __init__ (line 119) | def __init__(self, channels: List[BaseChannel]): method from_env (line 136) | def from_env( method from_config (line 158) | def from_config( method _make_enqueue_cb (line 249) | def _make_enqueue_cb(self, channel_id: str) -> Callable[[Any], None]: method _enqueue_one (line 257) | def _enqueue_one(self, channel_id: str, payload: Any) -> None: method enqueue (line 289) | def enqueue(self, channel_id: str, payload: Any) -> None: method _consume_channel_loop (line 307) | async def _consume_channel_loop( method start_all (line 350) | async def start_all(self) -> None: method stop_all (line 379) | async def stop_all(self) -> None: method get_channel (line 412) | async def get_channel(self, channel: str) -> Optional[BaseChannel]: method replace_channel (line 419) | async def replace_channel( method send_event (line 484) | async def send_event( method send_text (line 513) | async def send_text( FILE: src/copaw/app/channels/matrix/channel.py class MatrixChannel (line 45) | class MatrixChannel(BaseChannel): method __init__ (line 49) | def __init__( method _mxc_to_http (line 88) | def _mxc_to_http(self, mxc_url: str) -> str: method _check_allowlist (line 103) | def _check_allowlist( method from_env (line 116) | def from_env( method from_config (line 126) | def from_config( method build_agent_request_from_native (line 153) | def build_agent_request_from_native( method get_to_handle_from_request (line 175) | def get_to_handle_from_request(self, request: AgentRequest) -> str: method _handle_event (line 182) | async def _handle_event( method _message_callback (line 215) | async def _message_callback( method _media_callback (line 242) | async def _media_callback( method send_content_parts (line 281) | async def send_content_parts( method send_media (line 306) | async def send_media( # pylint: disable=too-many-branches method start (line 419) | async def start(self) -> None: method stop (line 478) | async def stop(self) -> None: method send (line 485) | async def send( FILE: src/copaw/app/channels/mattermost/channel.py function _download_mattermost_file (line 43) | async def _download_mattermost_file( class MattermostChannel (line 74) | class MattermostChannel(BaseChannel): method __init__ (line 100) | def __init__( method from_config (line 171) | def from_config( method from_env (line 210) | def from_env( method start (line 245) | async def start(self) -> None: method stop (line 255) | async def stop(self) -> None: method _init_bot_info (line 276) | async def _init_bot_info(self) -> bool: method _run (line 298) | async def _run(self) -> None: method _websocket_loop (line 305) | async def _websocket_loop(self) -> None: method _is_triggered (line 362) | def _is_triggered(self, post: dict, channel_type: str) -> bool: method _get_context_prefix (line 384) | async def _get_context_prefix( method _process_attachments (line 422) | async def _process_attachments(self, post: dict) -> list[Any]: method _on_posted_event (line 461) | async def _on_posted_event(self, event_data: dict) -> None: method _start_typing (line 576) | def _start_typing(self, mm_channel_id: str, root_id: str = "") -> None: method _stop_typing (line 583) | def _stop_typing(self, mm_channel_id: str) -> None: method _typing_loop (line 589) | async def _typing_loop( method _get_thread_target_order (line 621) | def _get_thread_target_order( method _fetch_thread_history (line 666) | async def _fetch_thread_history( method _fetch_channel_history (line 733) | async def _fetch_channel_history( method _download_file (line 771) | async def _download_file( method _upload_file (line 785) | async def _upload_file( method _post_message (line 828) | async def _post_message( method _chunk_text (line 863) | def _chunk_text(self, text: str) -> list[str]: method send (line 885) | async def send( method send_media (line 910) | async def send_media( method resolve_session_id (line 958) | def resolve_session_id( method build_agent_request_from_native (line 979) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method get_to_handle_from_request (line 998) | def get_to_handle_from_request(self, request: Any) -> str: method to_handle_from_target (line 1010) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: FILE: src/copaw/app/channels/mqtt/channel.py class MQTTChannel (line 29) | class MQTTChannel(BaseChannel): method __init__ (line 35) | def __init__( method from_env (line 86) | def from_env( method from_config (line 121) | def from_config( method _validate_config (line 196) | def _validate_config(self): method _on_connect (line 205) | def _on_connect( method _on_disconnect (line 223) | def _on_disconnect( method _on_message (line 235) | def _on_message(self, _client, _userdata, msg): method start (line 286) | async def start(self) -> None: method stop (line 345) | async def stop(self) -> None: method send (line 354) | async def send( method send_media (line 379) | async def send_media( method resolve_session_id (line 431) | def resolve_session_id( method get_to_handle_from_request (line 438) | def get_to_handle_from_request(self, request: Any) -> str: method build_agent_request_from_native (line 448) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method to_handle_from_target (line 467) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: FILE: src/copaw/app/channels/qq/channel.py class _MessageEventSpec (line 94) | class _MessageEventSpec: class _WSState (line 131) | class _WSState: class _HeartbeatController (line 143) | class _HeartbeatController: method __init__ (line 146) | def __init__( method start (line 158) | def start(self, interval_ms: float) -> None: method stop (line 162) | def stop(self) -> None: method _schedule (line 167) | def _schedule(self) -> None: method _send_ping (line 177) | def _send_ping(self) -> None: class QQApiError (line 193) | class QQApiError(RuntimeError): method __init__ (line 196) | def __init__(self, path: str, status: int, data: Any): function _sanitize_qq_text (line 203) | def _sanitize_qq_text(text: str) -> tuple[str, bool]: function _aggressive_sanitize_qq_text (line 214) | def _aggressive_sanitize_qq_text(text: str) -> tuple[str, bool]: function _is_url_content_error (line 226) | def _is_url_content_error(exc: Exception) -> bool: function _as_bool (line 241) | def _as_bool(value: Any) -> bool: function _should_plaintext_fallback_from_markdown (line 249) | def _should_plaintext_fallback_from_markdown(exc: Exception) -> bool: function _get_api_base (line 272) | def _get_api_base() -> str: function _get_channel_url_sync (line 277) | def _get_channel_url_sync(access_token: str) -> str: function _get_next_msg_seq (line 315) | def _get_next_msg_seq(msg_id: str) -> int: function _api_request_async (line 325) | async def _api_request_async( function _send_message_async (line 348) | async def _send_message_async( function _media_path (line 397) | def _media_path( function _upload_media_async (line 409) | async def _upload_media_async( function _send_media_message_async (line 439) | async def _send_media_message_async( function _download_qq_file (line 468) | async def _download_qq_file( class QQChannel (line 503) | class QQChannel(BaseChannel): method __init__ (line 510) | def __init__( method _get_access_token_sync (line 549) | def _get_access_token_sync(self) -> str: method _get_access_token_async (line 585) | async def _get_access_token_async(self) -> str: method _clear_token_cache (line 617) | def _clear_token_cache(self) -> None: method from_env (line 622) | def from_env( method from_config (line 638) | def from_config( method _resolve_send_path (line 661) | def _resolve_send_path( method _dispatch_text (line 695) | async def _dispatch_text( method _send_text_with_fallback (line 726) | async def _send_text_with_fallback( method _try_aggressive_url_fallback (line 816) | async def _try_aggressive_url_fallback( method _send_images (line 858) | async def _send_images( method send (line 899) | async def send( method _resolve_attachment_type (line 990) | def _resolve_attachment_type( method _download_attachment_sync (line 1009) | def _download_attachment_sync( method _make_content_part (line 1034) | def _make_content_part( method _parse_qq_attachments (line 1063) | def _parse_qq_attachments( method build_agent_request_from_native (line 1099) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method _handle_msg_event (line 1127) | def _handle_msg_event( method _handle_ws_payload (line 1188) | def _handle_ws_payload( method _compute_reconnect_delay (line 1279) | def _compute_reconnect_delay(self, state: _WSState) -> float: method _ws_connect_once (line 1308) | def _ws_connect_once( method _run_ws_forever (line 1378) | def _run_ws_forever(self) -> None: method start (line 1392) | async def start(self) -> None: method stop (line 1411) | async def stop(self) -> None: FILE: src/copaw/app/channels/registry.py function _load_builtin_channels (line 42) | def _load_builtin_channels() -> dict[str, type[BaseChannel]]: function _get_cached_builtin_channels (line 78) | def _get_cached_builtin_channels() -> dict[str, type[BaseChannel]]: function clear_builtin_channel_cache (line 87) | def clear_builtin_channel_cache() -> None: function _discover_custom_channels (line 94) | def _discover_custom_channels() -> dict[str, type[BaseChannel]]: function get_channel_registry (line 132) | def get_channel_registry() -> dict[str, type[BaseChannel]]: FILE: src/copaw/app/channels/renderer.py class RenderStyle (line 38) | class RenderStyle: function _fmt_tool_call (line 50) | def _fmt_tool_call( function _fmt_tool_output_label (line 64) | def _fmt_tool_output_label(name: str, style: RenderStyle) -> str: function _fmt_code_block (line 72) | def _fmt_code_block(preview: str, style: RenderStyle) -> str: class MessageRenderer (line 78) | class MessageRenderer: method __init__ (line 84) | def __init__(self, style: RenderStyle | None = None): method message_to_parts (line 87) | def message_to_parts(self, message: Any) -> List[_OutgoingPart]: method parts_to_text (line 352) | def parts_to_text( FILE: src/copaw/app/channels/schema.py class ChannelAddress (line 13) | class ChannelAddress: method to_handle (line 23) | def to_handle(self) -> str: class ChannelMessageConverter (line 52) | class ChannelMessageConverter(Protocol): method build_agent_request_from_native (line 58) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method send_response (line 64) | async def send_response( FILE: src/copaw/app/channels/telegram/channel.py class _FileTooLargeError (line 70) | class _FileTooLargeError(Exception): class _MediaFileUnavailableError (line 74) | class _MediaFileUnavailableError(Exception): function _download_telegram_file (line 78) | async def _download_telegram_file( function _resolve_telegram_file_url (line 114) | async def _resolve_telegram_file_url( function _build_content_parts_from_message (line 140) | async def _build_content_parts_from_message( function _message_meta (line 240) | def _message_meta(update: Any) -> dict: class TelegramChannel (line 264) | class TelegramChannel(BaseChannel): method __init__ (line 270) | def __init__( method _build_application (line 335) | def _build_application(self): method _apply_no_text_debounce (line 437) | def _apply_no_text_debounce( method from_env (line 454) | def from_env( method from_config (line 484) | def from_config( method _chunk_text (line 526) | def _chunk_text(self, text: str) -> list[str]: method _send_chat_action (line 548) | async def _send_chat_action( method _start_typing (line 567) | def _start_typing(self, chat_id: str) -> None: method _stop_typing (line 576) | def _stop_typing(self, chat_id: str) -> None: method _typing_loop (line 582) | async def _typing_loop(self, chat_id: str) -> None: method send (line 597) | async def send( method send_media (line 652) | async def send_media( # pylint: disable=too-many-statements method _send_media_value (line 769) | async def _send_media_value( method _send_media_payload (line 835) | async def _send_media_payload( method _polling_cycle (line 856) | async def _polling_cycle(self, app) -> None: method _teardown_application (line 913) | async def _teardown_application(app) -> None: method _run_polling (line 925) | async def _run_polling(self) -> None: method start (line 967) | async def start(self) -> None: method stop (line 981) | async def stop(self) -> None: method resolve_session_id (line 996) | def resolve_session_id( method get_to_handle_from_request (line 1008) | def get_to_handle_from_request(self, request: Any) -> str: method build_agent_request_from_native (line 1019) | def build_agent_request_from_native(self, native_payload: Any) -> Any: method to_handle_from_target (line 1039) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: FILE: src/copaw/app/channels/telegram/format_html.py function _escape_html (line 17) | def _escape_html(text: str) -> str: function markdown_to_telegram_html (line 22) | def markdown_to_telegram_html(text: str) -> str: function strip_markdown (line 165) | def strip_markdown(text: str) -> str: FILE: src/copaw/app/channels/utils.py function file_url_to_local_path (line 15) | def file_url_to_local_path(url: str) -> Optional[str]: function make_process_from_runner (line 58) | def make_process_from_runner(runner: Any): FILE: src/copaw/app/channels/voice/channel.py class VoiceChannel (line 17) | class VoiceChannel(BaseChannel): method __init__ (line 28) | def __init__( method from_config (line 54) | def from_config( method start (line 81) | async def start(self) -> None: method stop (line 138) | async def stop(self) -> None: method send (line 159) | async def send( method build_agent_request_from_native (line 171) | def build_agent_request_from_native( method config (line 202) | def config(self) -> Any: method process (line 207) | def process(self) -> ProcessHandler: method create_ws_token (line 213) | def create_ws_token(self) -> str: method validate_ws_token (line 223) | def validate_ws_token(self, token: str) -> bool: method get_tunnel_url (line 227) | def get_tunnel_url(self) -> str | None: method get_tunnel_wss_url (line 233) | def get_tunnel_wss_url(self) -> str | None: FILE: src/copaw/app/channels/voice/conversation_relay.py class ConversationRelayHandler (line 29) | class ConversationRelayHandler: method __init__ (line 44) | def __init__( method handle (line 60) | async def handle(self) -> None: method _handle_setup (line 103) | async def _handle_setup(self, msg: dict) -> None: method _handle_prompt (line 127) | async def _handle_prompt(self, msg: dict) -> None: method _handle_interrupt (line 144) | async def _handle_interrupt(self, msg: dict) -> None: method _handle_dtmf (line 155) | async def _handle_dtmf(self, msg: dict) -> None: method _build_agent_request (line 164) | def _build_agent_request(self, text: str) -> Any: method _process_and_stream (line 185) | async def _process_and_stream(self, request: Any) -> None: method _extract_text_from_event (line 228) | def _extract_text_from_event(event: Any) -> str: method _send_token (line 247) | async def _send_token( method send_text (line 269) | async def send_text(self, text: str) -> None: method close (line 273) | async def close(self) -> None: FILE: src/copaw/app/channels/voice/session.py class CallSession (line 17) | class CallSession: class CallSessionManager (line 28) | class CallSessionManager: method __init__ (line 31) | def __init__(self) -> None: method create_session (line 34) | def create_session( method get_session (line 56) | def get_session(self, call_sid: str) -> Optional[CallSession]: method end_session (line 59) | def end_session(self, call_sid: str) -> None: method active_sessions (line 65) | def active_sessions(self) -> list[CallSession]: method active_count (line 68) | def active_count(self) -> int: method all_sessions (line 71) | def all_sessions(self) -> list[CallSession]: FILE: src/copaw/app/channels/voice/twilio_manager.py class TwilioManager (line 12) | class TwilioManager: method __init__ (line 15) | def __init__(self, account_sid: str, auth_token: str) -> None: method _get_client (line 20) | def _get_client(self): method _run_sync (line 27) | async def _run_sync(self, fn, *args, **kwargs): method configure_voice_webhook (line 31) | async def configure_voice_webhook( FILE: src/copaw/app/channels/voice/twiml.py function build_conversation_relay_twiml (line 8) | def build_conversation_relay_twiml( function build_busy_twiml (line 40) | def build_busy_twiml( function build_error_twiml (line 54) | def build_error_twiml( FILE: src/copaw/app/channels/wecom/channel.py class WecomChannel (line 48) | class WecomChannel(BaseChannel): method __init__ (line 58) | def __init__( method from_env (line 108) | def from_env( method from_config (line 137) | def from_config( method resolve_session_id (line 173) | def resolve_session_id( method _parse_chatid_from_handle (line 189) | def _parse_chatid_from_handle(to_handle: str) -> str: method to_handle_from_target (line 202) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method get_to_handle_from_request (line 206) | def get_to_handle_from_request(self, request: Any) -> str: method get_on_reply_sent_args (line 211) | def get_on_reply_sent_args( method build_agent_request_from_native (line 221) | def build_agent_request_from_native( method merge_native_items (line 246) | def merge_native_items(self, items: List[Any]) -> Any: method _is_duplicate (line 275) | def _is_duplicate(self, msg_id: str) -> bool: method _on_message_sync (line 289) | def _on_message_sync(self, frame: Any) -> None: method _on_message (line 299) | async def _on_message(self, frame: Any) -> None: method _on_enter_chat_sync (line 478) | def _on_enter_chat_sync(self, frame: Any) -> None: method _on_enter_chat (line 488) | async def _on_enter_chat(self, frame: Any) -> None: method _download_media (line 502) | async def _download_media( method _send_text_via_frame (line 537) | async def _send_text_via_frame( method _send_image_via_send_message (line 564) | async def _send_image_via_send_message( method send_content_parts (line 587) | async def send_content_parts( method send (line 687) | async def send( method _run_ws_forever (line 735) | def _run_ws_forever(self) -> None: method start (line 770) | async def start(self) -> None: method stop (line 804) | async def stop(self) -> None: FILE: src/copaw/app/channels/wecom/utils.py function format_markdown_tables (line 9) | def format_markdown_tables(text: str) -> str: function _format_table (line 58) | def _format_table(lines: List[str]) -> List[str]: FILE: src/copaw/app/channels/xiaoyi/auth.py function generate_signature (line 15) | def generate_signature(sk: str, timestamp: str) -> str: function generate_auth_headers (line 31) | def generate_auth_headers(ak: str, sk: str, agent_id: str) -> Dict[str, ... FILE: src/copaw/app/channels/xiaoyi/channel.py class XiaoYiChannel (line 55) | class XiaoYiChannel(BaseChannel): method __init__ (line 65) | def __init__( method from_env (line 129) | def from_env( method from_config (line 152) | def from_config( method _validate_config (line 203) | def _validate_config(self) -> None: method start (line 212) | async def start(self) -> None: method _wait_and_register_connection (line 288) | async def _wait_and_register_connection(self) -> None: method _unregister_connection (line 339) | async def _unregister_connection(self) -> None: method _connect (line 350) | async def _connect(self) -> None: method _send_init_message (line 385) | async def _send_init_message(self) -> None: method _heartbeat_loop (line 400) | async def _heartbeat_loop(self) -> None: method _receive_loop (line 422) | async def _receive_loop(self) -> None: method _handle_message (line 449) | async def _handle_message(self, data: str) -> None: method _handle_a2a_request (line 491) | async def _handle_a2a_request(self, message: Dict[str, Any]) -> None: method _process_file_part (line 557) | async def _process_file_part( method _handle_clear_context (line 598) | async def _handle_clear_context(self, message: Dict[str, Any]) -> None: method _handle_tasks_cancel (line 612) | async def _handle_tasks_cancel(self, message: Dict[str, Any]) -> None: method _send_clear_context_response (line 623) | async def _send_clear_context_response( method _send_tasks_cancel_response (line 654) | async def _send_tasks_cancel_response( method _schedule_reconnect (line 686) | def _schedule_reconnect(self) -> None: method _cleanup_session (line 721) | async def _cleanup_session(self) -> None: method stop (line 737) | async def stop(self) -> None: method send (line 778) | async def send( method _chunk_text (line 815) | def _chunk_text(self, text: str) -> List[str]: method _build_artifact_msg (line 853) | def _build_artifact_msg( method _send_chunk (line 887) | async def _send_chunk( method _send_reasoning_chunk (line 908) | async def _send_reasoning_chunk( method send_final_message (line 929) | async def send_final_message( method send_media (line 951) | async def send_media( method _extract_xiaoyi_parts (line 1013) | def _extract_xiaoyi_parts( method send_xiaoyi_parts (line 1195) | async def send_xiaoyi_parts( method on_event_message_completed (line 1302) | async def on_event_message_completed( method resolve_session_id (line 1323) | def resolve_session_id( method get_to_handle_from_request (line 1333) | def get_to_handle_from_request(self, request: "AgentRequest") -> str: method build_agent_request_from_native (line 1340) | def build_agent_request_from_native( method to_handle_from_target (line 1365) | def to_handle_from_target(self, *, user_id: str, session_id: str) -> str: method _run_process_loop (line 1371) | async def _run_process_loop( FILE: src/copaw/app/channels/xiaoyi/utils.py function download_file (line 11) | async def download_file( FILE: src/copaw/app/console_push_store.py function append (line 22) | async def append(session_id: str, text: str, *, sticky: bool = False) ->... function take (line 41) | async def take(session_id: str) -> List[Dict[str, Any]]: function take_all (line 51) | async def take_all() -> List[Dict[str, Any]]: function _strip_ts (line 59) | def _strip_ts(msgs: List[Dict[str, Any]]) -> List[Dict[str, Any]]: function get_recent (line 70) | async def get_recent( FILE: src/copaw/app/crons/api.py function get_cron_manager (line 13) | async def get_cron_manager( function list_jobs (line 29) | async def list_jobs(mgr: CronManager = Depends(get_cron_manager)): function get_job (line 34) | async def get_job(job_id: str, mgr: CronManager = Depends(get_cron_manag... function create_job (line 42) | async def create_job( function replace_job (line 54) | async def replace_job( function delete_job (line 66) | async def delete_job( function pause_job (line 77) | async def pause_job(job_id: str, mgr: CronManager = Depends(get_cron_man... function resume_job (line 86) | async def resume_job( function run_job (line 98) | async def run_job(job_id: str, mgr: CronManager = Depends(get_cron_manag... function get_job_state (line 109) | async def get_job_state( FILE: src/copaw/app/crons/executor.py class CronExecutor (line 13) | class CronExecutor: method __init__ (line 14) | def __init__(self, *, runner: Any, channel_manager: Any): method execute (line 18) | async def execute(self, job: CronJobSpec) -> None: FILE: src/copaw/app/crons/heartbeat.py function parse_heartbeat_every (line 33) | def parse_heartbeat_every(every: str) -> int: function _in_active_hours (line 51) | def _in_active_hours(active_hours: Any) -> bool: function run_heartbeat_once (line 89) | async def run_heartbeat_once( FILE: src/copaw/app/crons/manager.py class _Runtime (line 28) | class _Runtime: class CronManager (line 32) | class CronManager: method __init__ (line 33) | def __init__( method start (line 57) | async def start(self) -> None: method stop (line 105) | async def stop(self) -> None: method list_jobs (line 114) | async def list_jobs(self) -> list[CronJobSpec]: method get_job (line 117) | async def get_job(self, job_id: str) -> Optional[CronJobSpec]: method get_state (line 120) | def get_state(self, job_id: str) -> CronJobState: method create_or_replace_job (line 125) | async def create_or_replace_job(self, spec: CronJobSpec) -> None: method delete_job (line 131) | async def delete_job(self, job_id: str) -> bool: method pause_job (line 139) | async def pause_job(self, job_id: str) -> None: method resume_job (line 143) | async def resume_job(self, job_id: str) -> None: method reschedule_heartbeat (line 147) | async def reschedule_heartbeat(self) -> None: method run_job (line 184) | async def run_job(self, job_id: str) -> None: method _task_done_cb (line 211) | def _task_done_cb(self, task: asyncio.Task, job: CronJobSpec) -> None: method _register_or_update (line 236) | async def _register_or_update(self, spec: CronJobSpec) -> None: method _build_trigger (line 268) | def _build_trigger(self, spec: CronJobSpec) -> CronTrigger: method _scheduled_callback (line 287) | async def _scheduled_callback(self, job_id: str) -> None: method _heartbeat_callback (line 300) | async def _heartbeat_callback(self) -> None: method _execute_once (line 320) | async def _execute_once(self, job: CronJobSpec) -> None: FILE: src/copaw/app/crons/models.py function _crontab_dow_to_name (line 37) | def _crontab_dow_to_name(field: str) -> str: class ScheduleSpec (line 58) | class ScheduleSpec(BaseModel): method normalize_cron_5_fields (line 65) | def normalize_cron_5_fields(cls, v: str) -> str: class DispatchTarget (line 88) | class DispatchTarget(BaseModel): class DispatchSpec (line 93) | class DispatchSpec(BaseModel): class JobRuntimeSpec (line 101) | class JobRuntimeSpec(BaseModel): class CronJobRequest (line 107) | class CronJobRequest(BaseModel): class CronJobSpec (line 123) | class CronJobSpec(BaseModel): method _validate_task_type_fields (line 138) | def _validate_task_type_fields(self) -> "CronJobSpec": class JobsFile (line 156) | class JobsFile(BaseModel): class CronJobState (line 161) | class CronJobState(BaseModel): class CronJobView (line 170) | class CronJobView(BaseModel): FILE: src/copaw/app/crons/repo/base.py class BaseJobRepository (line 10) | class BaseJobRepository(ABC): method load (line 14) | async def load(self) -> JobsFile: method save (line 19) | async def save(self, jobs_file: JobsFile) -> None: method list_jobs (line 25) | async def list_jobs(self) -> list[CronJobSpec]: method get_job (line 29) | async def get_job(self, job_id: str) -> Optional[CronJobSpec]: method upsert_job (line 36) | async def upsert_job(self, spec: CronJobSpec) -> None: method delete_job (line 46) | async def delete_job(self, job_id: str) -> bool: FILE: src/copaw/app/crons/repo/json_repo.py class JsonJobRepository (line 12) | class JsonJobRepository(BaseJobRepository): method __init__ (line 20) | def __init__(self, path: Path | str): method path (line 26) | def path(self) -> Path: method load (line 29) | async def load(self) -> JobsFile: method save (line 36) | async def save(self, jobs_file: JobsFile) -> None: FILE: src/copaw/app/download_task_store.py class DownloadTaskStatus (line 18) | class DownloadTaskStatus(str, Enum): class DownloadTask (line 26) | class DownloadTask(BaseModel): function create_task (line 43) | async def create_task( function get_tasks (line 61) | async def get_tasks(backend: Optional[str] = None) -> List[DownloadTask]: function get_task (line 70) | async def get_task(task_id: str) -> Optional[DownloadTask]: function update_status (line 76) | async def update_status( function cancel_task (line 96) | async def cancel_task(task_id: str) -> bool: function clear_completed (line 115) | async def clear_completed(backend: Optional[str] = None) -> None: FILE: src/copaw/app/mcp/manager.py class MCPClientManager (line 23) | class MCPClientManager: method __init__ (line 34) | def __init__(self) -> None: method init_from_config (line 39) | async def init_from_config(self, config: "MCPConfig") -> None: method get_clients (line 62) | async def get_clients(self) -> List[Any]: method replace_client (line 78) | async def replace_client( method remove_client (line 134) | async def remove_client(self, key: str) -> None: method close_all (line 150) | async def close_all(self) -> None: method _add_client (line 167) | async def _add_client( method _build_client (line 189) | def _build_client(client_config: "MCPClientConfig") -> Any: FILE: src/copaw/app/mcp/watcher.py class MCPConfigWatcher (line 26) | class MCPConfigWatcher: method __init__ (line 33) | def __init__( method start (line 69) | async def start(self) -> None: method stop (line 81) | async def stop(self) -> None: method _snapshot (line 112) | def _snapshot(self) -> None: method _load_mcp_config (line 129) | def _load_mcp_config(self) -> "MCPConfig": method _mcp_hash (line 138) | def _mcp_hash(mcp_config: "MCPConfig") -> int: method _poll_loop (line 142) | async def _poll_loop(self) -> None: method _check (line 151) | async def _check(self) -> None: method _reload_changed_clients_wrapper (line 192) | async def _reload_changed_clients_wrapper( method _reload_changed_clients (line 215) | async def _reload_changed_clients(self, new_mcp: "MCPConfig") -> None: method _handle_client_update (line 234) | async def _handle_client_update( method _reload_single_client (line 262) | async def _reload_single_client(self, key: str, new_cfg) -> None: method _should_skip_client (line 284) | def _should_skip_client(self, key: str, client_hash: int) -> bool: method _track_client_failure (line 297) | def _track_client_failure(self, key: str, client_hash: int) -> None: method _handle_client_removal (line 320) | async def _handle_client_removal(self, key: str) -> None: FILE: src/copaw/app/migration.py function migrate_legacy_workspace_to_default_agent (line 45) | def migrate_legacy_workspace_to_default_agent() -> bool: function _migrate_workspace_item (line 192) | def _migrate_workspace_item( function _migrate_workspace_items_from_source (line 226) | def _migrate_workspace_items_from_source( function ensure_default_agent_exists (line 247) | def ensure_default_agent_exists() -> None: FILE: src/copaw/app/multi_agent_manager.py class MultiAgentManager (line 17) | class MultiAgentManager: method __init__ (line 27) | def __init__(self): method get_agent (line 34) | async def get_agent(self, agent_id: str) -> Workspace: method _graceful_stop_old_instance (line 83) | async def _graceful_stop_old_instance( method stop_agent (line 180) | async def stop_agent(self, agent_id: str) -> bool: method reload_agent (line 200) | async def reload_agent(self, agent_id: str) -> bool: method cancel_all_cleanup_tasks (line 313) | async def cancel_all_cleanup_tasks(self) -> None: method stop_all (line 338) | async def stop_all(self): method list_loaded_agents (line 363) | def list_loaded_agents(self) -> list[str]: method is_agent_loaded (line 371) | def is_agent_loaded(self, agent_id: str) -> bool: method preload_agent (line 382) | async def preload_agent(self, agent_id: str) -> bool: method start_all_configured_agents (line 399) | async def start_all_configured_agents(self) -> dict[str, bool]: method __repr__ (line 447) | def __repr__(self) -> str: FILE: src/copaw/app/routers/__init__.py function create_agent_scoped_router (line 44) | def create_agent_scoped_router() -> APIRouter: FILE: src/copaw/app/routers/agent.py class MdFileInfo (line 23) | class MdFileInfo(BaseModel): class MdFileContent (line 33) | class MdFileContent(BaseModel): function list_working_files (line 45) | async def list_working_files( function read_working_file (line 69) | async def read_working_file( function write_working_file (line 93) | async def write_working_file( function list_memory_files (line 116) | async def list_memory_files( function read_memory_file (line 140) | async def read_memory_file( function write_memory_file (line 164) | async def write_memory_file( function get_agent_language (line 186) | async def get_agent_language(request: Request) -> dict: function put_agent_language (line 204) | async def put_agent_language( function get_audio_mode (line 263) | async def get_audio_mode() -> dict: function put_audio_mode (line 278) | async def put_audio_mode( function get_transcription_provider_type (line 310) | async def get_transcription_provider_type() -> dict: function put_transcription_provider_type (line 330) | async def put_transcription_provider_type( function get_local_whisper_status (line 365) | async def get_local_whisper_status() -> dict: function get_transcription_providers (line 382) | async def get_transcription_providers() -> dict: function put_transcription_provider (line 403) | async def put_transcription_provider( function get_agents_running_config (line 426) | async def get_agents_running_config( function put_agents_running_config (line 441) | async def put_agents_running_config( function get_system_prompt_files (line 479) | async def get_system_prompt_files( function put_system_prompt_files (line 494) | async def put_system_prompt_files( FILE: src/copaw/app/routers/agent_scoped.py class AgentContextMiddleware (line 15) | class AgentContextMiddleware(BaseHTTPMiddleware): method dispatch (line 18) | async def dispatch( function create_agent_scoped_router (line 53) | def create_agent_scoped_router() -> APIRouter: FILE: src/copaw/app/routers/agents.py class AgentSummary (line 31) | class AgentSummary(BaseModel): class AgentListResponse (line 40) | class AgentListResponse(BaseModel): class CreateAgentRequest (line 46) | class CreateAgentRequest(BaseModel): class MdFileInfo (line 55) | class MdFileInfo(BaseModel): class MdFileContent (line 65) | class MdFileContent(BaseModel): function _get_multi_agent_manager (line 71) | def _get_multi_agent_manager(request: Request) -> MultiAgentManager: function list_agents (line 87) | async def list_agents() -> AgentListResponse: function get_agent (line 126) | async def get_agent(agentId: str = PathParam(...)) -> AgentProfileConfig: function create_agent (line 144) | async def create_agent( function update_agent (line 218) | async def update_agent( function delete_agent (line 268) | async def delete_agent( function list_agent_files (line 307) | async def list_agent_files( function read_agent_file (line 337) | async def read_agent_file( function write_agent_file (line 370) | async def write_agent_file( function list_agent_memory (line 399) | async def list_agent_memory( function _initialize_agent_workspace (line 423) | def _initialize_agent_workspace( # pylint: disable=too-many-branches FILE: src/copaw/app/routers/auth.py class LoginRequest (line 21) | class LoginRequest(BaseModel): class LoginResponse (line 26) | class LoginResponse(BaseModel): class RegisterRequest (line 31) | class RegisterRequest(BaseModel): class AuthStatusResponse (line 36) | class AuthStatusResponse(BaseModel): function login (line 42) | async def login(req: LoginRequest): function register (line 55) | async def register(req: RegisterRequest): function auth_status (line 87) | async def auth_status(): function verify (line 96) | async def verify(request: Request): FILE: src/copaw/app/routers/config.py function list_channels (line 64) | async def list_channels(request: Request) -> dict: function list_channel_types (line 106) | async def list_channel_types() -> List[str]: function put_channels (line 117) | async def put_channels( function get_channel (line 161) | async def get_channel( function put_channel (line 205) | async def put_channel( function get_heartbeat (line 273) | async def get_heartbeat(request: Request) -> Any: function put_heartbeat (line 291) | async def put_heartbeat( function get_agents_llm_routing (line 333) | async def get_agents_llm_routing() -> AgentsLLMRoutingConfig: function put_agents_llm_routing (line 343) | async def put_agents_llm_routing( function get_user_timezone (line 360) | async def get_user_timezone() -> dict: function put_user_timezone (line 370) | async def put_user_timezone( function get_tool_guard (line 390) | async def get_tool_guard() -> ToolGuardConfig: function put_tool_guard (line 400) | async def put_tool_guard( function get_builtin_rules (line 421) | async def get_builtin_rules() -> List[ToolGuardRuleConfig]: function get_skill_scanner (line 451) | async def get_skill_scanner() -> SkillScannerConfig: function put_skill_scanner (line 461) | async def put_skill_scanner( function get_blocked_history (line 474) | async def get_blocked_history() -> list: function delete_blocked_history (line 485) | async def delete_blocked_history() -> dict: function delete_blocked_entry (line 496) | async def delete_blocked_entry( class WhitelistAddRequest (line 507) | class WhitelistAddRequest(BaseModel): function add_to_whitelist (line 516) | async def add_to_whitelist( function remove_from_whitelist (line 549) | async def remove_from_whitelist( FILE: src/copaw/app/routers/console.py function _safe_filename (line 26) | def _safe_filename(name: str) -> str: function _extract_session_and_payload (line 32) | def _extract_session_and_payload(request_data: Union[AgentRequest, dict]): function post_console_chat (line 75) | async def post_console_chat( function post_console_chat_stop (line 153) | async def post_console_chat_stop( function post_console_upload (line 164) | async def post_console_upload( function get_console_file (line 197) | async def get_console_file( function get_push_messages (line 227) | async def get_push_messages( FILE: src/copaw/app/routers/envs.py class EnvVar (line 20) | class EnvVar(BaseModel): function list_envs (line 37) | async def list_envs() -> List[EnvVar]: function batch_save_envs (line 50) | async def batch_save_envs( function delete_env (line 71) | async def delete_env(key: str) -> List[EnvVar]: FILE: src/copaw/app/routers/local_models.py class DownloadRequest (line 33) | class DownloadRequest(BaseModel): class LocalModelResponse (line 46) | class LocalModelResponse(BaseModel): class DownloadTaskResponse (line 57) | class DownloadTaskResponse(BaseModel): function _task_to_response (line 68) | def _task_to_response(task: DownloadTask) -> DownloadTaskResponse: function _register_background_task (line 84) | async def _register_background_task(task_id: str, task: asyncio.Task) ->... function _pop_background_task (line 89) | async def _pop_background_task(task_id: str) -> Optional[asyncio.Task]: function list_local (line 99) | async def list_local( function download_model (line 128) | async def download_model( function _run_download_in_background (line 170) | async def _run_download_in_background( function get_download_status (line 263) | async def get_download_status( function delete_local (line 274) | async def delete_local(model_id: str) -> dict: function _cancel_download_task (line 293) | async def _cancel_download_task(task_id: str) -> dict: function cancel_download (line 317) | async def cancel_download(task_id: str) -> dict: FILE: src/copaw/app/routers/mcp.py class MCPClientInfo (line 16) | class MCPClientInfo(BaseModel): class MCPClientCreateRequest (line 53) | class MCPClientCreateRequest(BaseModel): class MCPClientUpdateRequest (line 92) | class MCPClientUpdateRequest(BaseModel): function _mask_env_value (line 131) | def _mask_env_value(value: str) -> str: function _build_client_info (line 162) | def _build_client_info(key: str, client: MCPClientConfig) -> MCPClientInfo: function list_mcp_clients (line 196) | async def list_mcp_clients(request: Request) -> List[MCPClientInfo]: function get_mcp_client (line 216) | async def get_mcp_client( function create_mcp_client (line 240) | async def create_mcp_client( function update_mcp_client (line 309) | async def update_mcp_client( function toggle_mcp_client (line 370) | async def toggle_mcp_client( function delete_mcp_client (line 417) | async def delete_mcp_client( FILE: src/copaw/app/routers/ollama_models.py class OllamaDownloadRequest (line 40) | class OllamaDownloadRequest(BaseModel): class OllamaModelResponse (line 44) | class OllamaModelResponse(BaseModel): class OllamaDownloadTaskResponse (line 51) | class OllamaDownloadTaskResponse(BaseModel): function _is_ollama_connection_error (line 59) | def _is_ollama_connection_error(exc: Exception) -> bool: function _task_to_response (line 71) | def _task_to_response(task: DownloadTask) -> OllamaDownloadTaskResponse: function _register_background_task (line 84) | async def _register_background_task(task_id: str, task: asyncio.Task) ->... function _pop_background_task (line 89) | async def _pop_background_task(task_id: str) -> Optional[asyncio.Task]: function _run_ollama_download_in_background (line 94) | async def _run_ollama_download_in_background( function list_ollama_models (line 157) | async def list_ollama_models( function download_ollama_model (line 198) | async def download_ollama_model( function get_ollama_download_status (line 237) | async def get_ollama_download_status() -> List[OllamaDownloadTaskResponse]: function cancel_ollama_download (line 247) | async def cancel_ollama_download(task_id: str) -> dict: function delete_ollama_model (line 270) | async def delete_ollama_model( FILE: src/copaw/app/routers/providers.py function get_provider_manager (line 31) | def get_provider_manager(request: Request) -> ProviderManager: class ProviderConfigRequest (line 43) | class ProviderConfigRequest(BaseModel): class ModelSlotRequest (line 60) | class ModelSlotRequest(BaseModel): class CreateCustomProviderRequest (line 65) | class CreateCustomProviderRequest(BaseModel): class AddModelRequest (line 74) | class AddModelRequest(BaseModel): function list_all_providers (line 84) | async def list_all_providers( function configure_provider (line 95) | async def configure_provider( function create_custom_provider_endpoint (line 130) | async def create_custom_provider_endpoint( class TestConnectionResponse (line 151) | class TestConnectionResponse(BaseModel): class TestProviderRequest (line 156) | class TestProviderRequest(BaseModel): class TestModelRequest (line 171) | class TestModelRequest(BaseModel): class DiscoverModelsRequest (line 175) | class DiscoverModelsRequest(BaseModel): class DiscoverModelsResponse (line 190) | class DiscoverModelsResponse(BaseModel): function test_provider (line 211) | async def test_provider( function discover_models (line 243) | async def discover_models( function test_model (line 279) | async def test_model( function delete_custom_provider_endpoint (line 307) | async def delete_custom_provider_endpoint( function add_model_endpoint (line 326) | async def add_model_endpoint( function remove_model_endpoint (line 346) | async def remove_model_endpoint( function get_active_models (line 366) | async def get_active_models( function set_active_model (line 405) | async def set_active_model( FILE: src/copaw/app/routers/schemas_config.py class HeartbeatBody (line 11) | class HeartbeatBody(BaseModel): FILE: src/copaw/app/routers/skills.py function _scan_error_response (line 28) | def _scan_error_response(exc: SkillScanError) -> JSONResponse: class SkillSpec (line 53) | class SkillSpec(SkillInfo): class CreateSkillRequest (line 57) | class CreateSkillRequest(BaseModel): class HubSkillSpec (line 74) | class HubSkillSpec(BaseModel): class HubInstallRequest (line 82) | class HubInstallRequest(BaseModel): class HubInstallTaskStatus (line 92) | class HubInstallTaskStatus(str, Enum): class HubInstallTask (line 100) | class HubInstallTask(BaseModel): function list_skills (line 123) | async def list_skills( function get_available_skills (line 165) | async def get_available_skills( function search_hub (line 197) | async def search_hub( function _hub_task_set_status (line 214) | async def _hub_task_set_status( function _hub_task_get (line 233) | async def _hub_task_get(task_id: str) -> HubInstallTask | None: function _hub_task_register_runtime (line 238) | async def _hub_task_register_runtime(task_id: str, task: asyncio.Task) -... function _hub_task_pop_runtime (line 243) | async def _hub_task_pop_runtime(task_id: str) -> asyncio.Task | None: function _cleanup_imported_skill (line 248) | def _cleanup_imported_skill(workspace_dir: Path, skill_name: str) -> None: function _run_hub_install_task (line 264) | async def _run_hub_install_task( function install_from_hub (line 345) | async def install_from_hub( function start_install_from_hub (line 392) | async def start_install_from_hub( function get_hub_install_status (line 425) | async def get_hub_install_status(task_id: str) -> HubInstallTask: function cancel_hub_install (line 433) | async def cancel_hub_install(task_id: str) -> dict[str, Any]: function upload_skill_zip (line 464) | async def upload_skill_zip( function batch_disable_skills (line 518) | async def batch_disable_skills( function batch_enable_skills (line 533) | async def batch_enable_skills( function create_skill (line 569) | async def create_skill( function disable_skill (line 592) | async def disable_skill( function enable_skill (line 627) | async def enable_skill( function delete_skill (line 697) | async def delete_skill( function load_skill_file (line 717) | async def load_skill_file( FILE: src/copaw/app/routers/skills_stream.py function get_model (line 19) | def get_model(): class AIOptimizeSkillRequest (line 116) | class AIOptimizeSkillRequest(BaseModel): function _extract_text_from_chunk (line 127) | def _extract_text_from_chunk(chunk) -> str: function _extract_text_from_response (line 150) | def _extract_text_from_response(response) -> str: function ai_optimize_skill_stream (line 167) | async def ai_optimize_skill_stream(request: AIOptimizeSkillRequest): FILE: src/copaw/app/routers/token_usage.py function _parse_date (line 13) | def _parse_date(s: str | None) -> date | None: function get_token_usage (line 28) | async def get_token_usage( FILE: src/copaw/app/routers/tools.py class ToolInfo (line 21) | class ToolInfo(BaseModel): function list_tools (line 30) | async def list_tools( function toggle_tool (line 69) | async def toggle_tool( FILE: src/copaw/app/routers/voice.py function _get_voice_channel (line 28) | def _get_voice_channel(request_or_ws): function _validate_twilio_signature (line 42) | async def _validate_twilio_signature(request: Request) -> None: function voice_incoming (line 88) | async def voice_incoming(request: Request) -> Response: function voice_ws (line 126) | async def voice_ws(websocket: WebSocket) -> None: function voice_status_callback (line 167) | async def voice_status_callback(request: Request) -> Response: FILE: src/copaw/app/routers/workspace.py function _dir_stats (line 21) | def _dir_stats(root: Path) -> tuple[int, int]: function _zip_directory (line 33) | def _zip_directory(root: Path) -> io.BytesIO: function _validate_zip_data (line 56) | def _validate_zip_data(data: bytes, workspace_dir: Path) -> None: function _extract_and_merge_zip (line 73) | def _extract_and_merge_zip(data: bytes, workspace_dir: Path) -> None: function _validate_and_extract_zip (line 101) | def _validate_and_extract_zip(data: bytes, workspace_dir: Path) -> None: function download_workspace (line 126) | async def download_workspace(request: Request): function upload_workspace (line 165) | async def upload_workspace( FILE: src/copaw/app/runner/api.py function get_workspace (line 21) | async def get_workspace(request: Request): function get_chat_manager (line 28) | async def get_chat_manager( function get_session (line 46) | async def get_session( function list_chats (line 65) | async def list_chats( function create_chat (line 88) | async def create_chat( function batch_delete_chats (line 116) | async def batch_delete_chats( function get_chat (line 134) | async def get_chat( function update_chat (line 178) | async def update_chat( function delete_chat (line 215) | async def delete_chat( FILE: src/copaw/app/runner/command_dispatch.py function _get_last_user_text (line 28) | def _get_last_user_text(msgs) -> str | None: function _is_conversation_command (line 46) | def _is_conversation_command(query: str | None) -> bool: function _is_command (line 54) | def _is_command(query: str | None) -> bool: function run_command_path (line 63) | async def run_command_path( FILE: src/copaw/app/runner/daemon_commands.py class RestartInProgressError (line 28) | class RestartInProgressError(Exception): class DaemonContext (line 49) | class DaemonContext: function _get_last_lines (line 62) | def _get_last_lines( function run_daemon_status (line 97) | def run_daemon_status(context: DaemonContext) -> str: function run_daemon_restart (line 126) | async def run_daemon_restart(context: DaemonContext) -> str: function run_daemon_reload_config (line 153) | def run_daemon_reload_config(context: DaemonContext) -> str: function run_daemon_version (line 164) | def run_daemon_version(context: DaemonContext) -> str: function run_daemon_logs (line 178) | def run_daemon_logs(context: DaemonContext, lines: int = 100) -> str: function run_daemon_approve (line 185) | async def run_daemon_approve( function parse_daemon_query (line 225) | def parse_daemon_query(query: str) -> Optional[tuple[str, list[str]]]: class DaemonCommandHandlerMixin (line 254) | class DaemonCommandHandlerMixin: method is_daemon_command (line 257) | def is_daemon_command(self, query: str | None) -> bool: method handle_daemon_command (line 261) | async def handle_daemon_command( FILE: src/copaw/app/runner/manager.py class ChatManager (line 17) | class ChatManager: method __init__ (line 26) | def __init__( method list_chats (line 44) | async def list_chats( method get_chat (line 68) | async def get_chat(self, chat_id: str) -> Optional[ChatSpec]: method get_or_create_chat (line 80) | async def get_or_create_chat( method create_chat (line 137) | async def create_chat(self, spec: ChatSpec) -> ChatSpec: method update_chat (line 150) | async def update_chat(self, spec: ChatSpec) -> ChatSpec: method delete_chats (line 164) | async def delete_chats(self, chat_ids: list[str]) -> bool: method count_chats (line 183) | async def count_chats( FILE: src/copaw/app/runner/models.py class ChatSpec (line 15) | class ChatSpec(BaseModel): class ChatHistory (line 51) | class ChatHistory(BaseModel): class ChatsFile (line 61) | class ChatsFile(BaseModel): FILE: src/copaw/app/runner/query_error_dump.py function _safe_json_serialize (line 18) | def _safe_json_serialize(obj: object) -> object: function _request_to_dict (line 29) | def _request_to_dict(request: Any) -> Any: function write_query_error_dump (line 48) | def write_query_error_dump( FILE: src/copaw/app/runner/repo/base.py class BaseChatRepository (line 12) | class BaseChatRepository(ABC): method load (line 16) | async def load(self) -> ChatsFile: method save (line 21) | async def save(self, chats_file: ChatsFile) -> None: method list_chats (line 27) | async def list_chats(self) -> list[ChatSpec]: method get_chat (line 32) | async def get_chat(self, chat_id: str) -> Optional[ChatSpec]: method get_chat_by_id (line 47) | async def get_chat_by_id( method upsert_chat (line 87) | async def upsert_chat(self, spec: ChatSpec) -> None: method delete_chats (line 102) | async def delete_chats(self, chat_ids: list[str]) -> bool: method filter_chats (line 122) | async def filter_chats( FILE: src/copaw/app/runner/repo/json_repo.py class JsonChatRepository (line 13) | class JsonChatRepository(BaseChatRepository): method __init__ (line 24) | def __init__(self, path: Path | str): method path (line 35) | def path(self) -> Path: method load (line 39) | async def load(self) -> ChatsFile: method save (line 51) | async def save(self, chats_file: ChatsFile) -> None: FILE: src/copaw/app/runner/runner.py function _is_approval (line 52) | def _is_approval(text: str) -> bool: class AgentRunner (line 63) | class AgentRunner(Runner): method __init__ (line 64) | def __init__( method set_chat_manager (line 79) | def set_chat_manager(self, chat_manager): method set_mcp_manager (line 87) | def set_mcp_manager(self, mcp_manager): method _resolve_pending_approval (line 97) | async def _resolve_pending_approval( method query_handler (line 175) | async def query_handler( method _cleanup_denied_session_memory (line 379) | async def _cleanup_denied_session_memory( method init_handler (line 489) | async def init_handler(self, *args, **kwargs): method shutdown_handler (line 511) | async def shutdown_handler(self, *args, **kwargs): FILE: src/copaw/app/runner/session.py function sanitize_filename (line 26) | def sanitize_filename(name: str) -> str: class SafeJSONSession (line 37) | class SafeJSONSession(SessionBase): method __init__ (line 44) | def __init__( method _get_save_path (line 56) | def _get_save_path(self, session_id: str, user_id: str) -> str: method save_session_state (line 71) | async def save_session_state( method load_session_state (line 95) | async def load_session_state( method update_session_state (line 134) | async def update_session_state( method get_session_state_dict (line 186) | async def get_session_state_dict( FILE: src/copaw/app/runner/task_tracker.py class _RunState (line 23) | class _RunState: class TaskTracker (line 31) | class TaskTracker: method __init__ (line 38) | def __init__(self) -> None: method lock (line 43) | def lock(self) -> asyncio.Lock: method get_status (line 46) | async def get_status(self, run_key: str) -> str: method has_active_tasks (line 54) | async def has_active_tasks(self) -> bool: method list_active_tasks (line 66) | async def list_active_tasks(self) -> list[str]: method wait_all_done (line 79) | async def wait_all_done(self, timeout: float = 300.0) -> bool: method attach (line 99) | async def attach(self, run_key: str) -> asyncio.Queue | None: method request_stop (line 115) | async def request_stop(self, run_key: str) -> bool: method attach_or_start (line 124) | async def attach_or_start( method stream_from_queue (line 210) | async def stream_from_queue( FILE: src/copaw/app/runner/utils.py function build_env_context (line 30) | def build_env_context( function _is_local_file_url (line 93) | def _is_local_file_url(url: str) -> bool: function _basename_from_url (line 114) | def _basename_from_url(url: str) -> str: function _resolve_content_url (line 122) | def _resolve_content_url(url: str) -> str: function agentscope_msg_to_message (line 132) | def agentscope_msg_to_message( FILE: src/copaw/app/workspace/service_factories.py function create_mcp_service (line 18) | async def create_mcp_service(ws: "Workspace", mcp): function create_chat_service (line 36) | async def create_chat_service(ws: "Workspace", service): function create_channel_service (line 64) | async def create_channel_service(ws: "Workspace", _): function create_agent_config_watcher (line 104) | async def create_agent_config_watcher(ws: "Workspace", _): function create_mcp_config_watcher (line 134) | async def create_mcp_config_watcher(ws: "Workspace", _): FILE: src/copaw/app/workspace/service_manager.py class ServiceDescriptor (line 31) | class ServiceDescriptor: class ServiceManager (line 74) | class ServiceManager: method __init__ (line 81) | def __init__(self, workspace: Workspace): method register (line 92) | def register(self, descriptor: ServiceDescriptor) -> None: method set_reusable (line 106) | async def set_reusable(self, name: str, instance: Any) -> None: method get_reusable_services (line 146) | def get_reusable_services(self) -> Dict[str, Any]: method _group_by_priority (line 158) | def _group_by_priority(self) -> Dict[int, List[ServiceDescriptor]]: method start_all (line 171) | async def start_all(self) -> None: method _start_service (line 201) | async def _start_service(self, descriptor: ServiceDescriptor) -> None: method _get_or_create_service (line 230) | async def _get_or_create_service( method _run_post_init (line 262) | async def _run_post_init( method _run_start_method (line 297) | async def _run_start_method( method stop_all (line 324) | async def stop_all(self, final: bool = False) -> None: method _stop_service (line 361) | async def _stop_service( FILE: src/copaw/app/workspace/workspace.py class Workspace (line 39) | class Workspace: method __init__ (line 52) | def __init__(self, agent_id: str, workspace_dir: str): method runner (line 81) | def runner(self) -> Optional[AgentRunner]: method memory_manager (line 86) | def memory_manager(self): method mcp_manager (line 91) | def mcp_manager(self): method chat_manager (line 96) | def chat_manager(self): method channel_manager (line 101) | def channel_manager(self): method cron_manager (line 106) | def cron_manager(self): method task_tracker (line 112) | def task_tracker(self) -> TaskTracker: method config (line 117) | def config(self): method set_manager (line 123) | def set_manager(self, manager) -> None: method _register_services (line 134) | def _register_services( # pylint: disable=too-many-statements method set_reusable_components (line 279) | async def set_reusable_components(self, components: dict) -> None: method start (line 311) | async def start(self): method stop (line 338) | async def stop(self, final: bool = True): method __repr__ (line 359) | def __repr__(self) -> str: FILE: src/copaw/cli/app_cmd.py function app_cmd (line 54) | def app_cmd( FILE: src/copaw/cli/auth_cmd.py function auth_group (line 17) | def auth_group() -> None: function reset_password_cmd (line 22) | def reset_password_cmd() -> None: FILE: src/copaw/cli/channels_cmd.py function _get_channel_names (line 159) | def _get_channel_names() -> dict[str, str]: function _mask (line 177) | def _mask(value: str) -> str: function configure_imessage (line 189) | def configure_imessage( function configure_discord (line 229) | def configure_discord(current_config: DiscordConfig) -> DiscordConfig: function configure_dingtalk (line 294) | def configure_dingtalk(current_config: DingTalkConfig) -> DingTalkConfig: function configure_feishu (line 334) | def configure_feishu(current_config: FeishuConfig) -> FeishuConfig: function configure_qq (line 374) | def configure_qq(current_config: QQConfig) -> QQConfig: function configure_telegram (line 420) | def configure_telegram(current_config: TelegramConfig) -> TelegramConfig: function configure_voice (line 497) | def configure_voice( function configure_console (line 596) | def configure_console(current_config: ConsoleConfig) -> ConsoleConfig: function _plugin_configure (line 636) | def _plugin_configure( function get_channel_configurators (line 656) | def get_channel_configurators() -> dict: function _get_channel_config (line 727) | def _get_channel_config(config: Config, key: str): function configure_channels_interactive (line 736) | def configure_channels_interactive(config: Config) -> None: function channels_group (line 800) | def channels_group() -> None: function _channel_config_fields (line 805) | def _channel_config_fields(ch): function _channel_enabled (line 824) | def _channel_enabled(ch) -> bool: function list_cmd (line 841) | def list_cmd(agent_id: str) -> None: function _install_channel_to_dir (line 883) | def _install_channel_to_dir( function install_cmd (line 965) | def install_cmd(key: str, from_path: str | None, from_url: str | None) -... function add_cmd (line 992) | def add_cmd( function remove_cmd (line 1036) | def remove_cmd(key: str, keep_config: bool) -> None: function configure_cmd (line 1084) | def configure_cmd(agent_id: str) -> None: FILE: src/copaw/cli/chats_cmd.py function _base_url (line 15) | def _base_url(ctx: click.Context, base_url: Optional[str]) -> str: function chats_group (line 29) | def chats_group() -> None: function list_chats (line 64) | def list_chats( function get_chat (line 102) | def get_chat( function create_chat (line 166) | def create_chat( function update_chat (line 228) | def update_chat( function delete_chat (line 275) | def delete_chat( FILE: src/copaw/cli/clean_cmd.py function _iter_children (line 13) | def _iter_children(p: Path) -> list[Path]: function clean_cmd (line 27) | def clean_cmd(yes: bool, dry_run: bool) -> None: FILE: src/copaw/cli/cron_cmd.py function _base_url (line 14) | def _base_url(ctx: click.Context, base_url: Optional[str]) -> str: function cron_group (line 28) | def cron_group() -> None: function list_jobs (line 51) | def list_jobs( function get_job (line 78) | def get_job( function job_state (line 108) | def job_state( function _build_spec_from_cli (line 125) | def _build_spec_from_cli( function create_job (line 299) | def create_job( function delete_job (line 373) | def delete_job( function pause_job (line 403) | def pause_job( function resume_job (line 435) | def resume_job( function run_job (line 465) | def run_job( FILE: src/copaw/cli/daemon_cmd.py function _get_agent_workspace (line 25) | def _get_agent_workspace(agent_id: str) -> Path: function _context (line 38) | def _context(agent_id: str) -> DaemonContext: function daemon_group (line 49) | def daemon_group() -> None: function status_cmd (line 59) | def status_cmd(agent_id: str) -> None: function restart_cmd (line 72) | def restart_cmd(agent_id: str) -> None: function reload_config_cmd (line 85) | def reload_config_cmd(agent_id: str) -> None: function version_cmd (line 98) | def version_cmd(agent_id: str) -> None: function logs_cmd (line 118) | def logs_cmd(lines: int, agent_id: str) -> None: FILE: src/copaw/cli/desktop_cmd.py class WebViewAPI (line 29) | class WebViewAPI: method open_external_link (line 32) | def open_external_link(self, url: str) -> None: function _find_free_port (line 39) | def _find_free_port(host: str = "127.0.0.1") -> int: function _wait_for_http (line 47) | def _wait_for_http(host: str, port: int, timeout_sec: float = 300.0) -> ... function _stream_reader (line 61) | def _stream_reader(in_stream, out_stream) -> None: function desktop_cmd (line 99) | def desktop_cmd( FILE: src/copaw/cli/env_cmd.py function env_group (line 11) | def env_group() -> None: function list_cmd (line 21) | def list_cmd() -> None: function set_cmd (line 42) | def set_cmd(key: str, value: str) -> None: function delete_cmd (line 55) | def delete_cmd(key: str) -> None: function configure_env_interactive (line 75) | def configure_env_interactive() -> None: FILE: src/copaw/cli/http.py function client (line 14) | def client(base_url: str) -> httpx.Client: function print_json (line 23) | def print_json(data: Any) -> None: FILE: src/copaw/cli/init_cmd.py function _echo_security_warning_box (line 73) | def _echo_security_warning_box() -> None: function _echo_telemetry_info_box (line 85) | def _echo_telemetry_info_box() -> None: function init_cmd (line 138) | def init_cmd( FILE: src/copaw/cli/main.py function _record (line 28) | def _record(label: str, elapsed: float) -> None: function log_init_timings (line 124) | def log_init_timings() -> None: function cli (line 140) | def cli(ctx: click.Context, host: str | None, port: int | None) -> None: FILE: src/copaw/cli/process_utils.py function _coerce_optional_int (line 16) | def _coerce_optional_int(value: object) -> Optional[int]: function _parse_windows_process_snapshot_json (line 30) | def _parse_windows_process_snapshot_json( function _parse_windows_process_snapshot_csv (line 62) | def _parse_windows_process_snapshot_csv( function _windows_process_snapshot (line 85) | def _windows_process_snapshot() -> dict[int, tuple[Optional[int], str, s... function _process_table (line 131) | def _process_table() -> list[tuple[int, str]]: function _matches_copaw_cli_command (line 167) | def _matches_copaw_cli_command(command: str, *subcommands: str) -> bool: function _is_copaw_service_command (line 183) | def _is_copaw_service_command(command: str) -> bool: function _is_copaw_wrapper_process (line 188) | def _is_copaw_wrapper_process(name: str, command: str) -> bool: function _extract_port_from_command (line 198) | def _extract_port_from_command(command: str, default: int = 8088) -> int: function _base_url (line 204) | def _base_url(host: str, port: int) -> str: function _candidate_hosts (line 212) | def _candidate_hosts(host: str | None) -> list[str]: FILE: src/copaw/cli/providers_cmd.py function _manager (line 16) | def _manager() -> ProviderManager: function _mask_api_key (line 20) | def _mask_api_key(api_key: str) -> str: function _is_configured (line 28) | def _is_configured(provider: Provider) -> bool: function _save_provider (line 40) | def _save_provider(manager: ProviderManager, provider_id: str) -> None: function _all_provider_objects (line 50) | def _all_provider_objects(manager: ProviderManager) -> list[Provider]: function _get_ollama_host (line 59) | def _get_ollama_host() -> str: function _select_provider_interactive (line 67) | def _select_provider_interactive( function configure_provider_api_key_interactive (line 95) | def configure_provider_api_key_interactive( function _add_models_interactive (line 179) | def _add_models_interactive(provider_id: str) -> None: function _pick_model_from_list (line 230) | def _pick_model_from_list( function _pick_model_free_text (line 246) | def _pick_model_free_text(prompt_text: str, current_model: str = "") -> ... function _filter_eligible (line 254) | def _filter_eligible(all_providers: list[Provider]) -> list[Provider]: function _select_llm_model (line 258) | def _select_llm_model(defn, pid, current_slot, *, use_defaults): function configure_llm_slot_interactive (line 284) | def configure_llm_slot_interactive(*, use_defaults: bool = False) -> None: function configure_providers_interactive (line 371) | def configure_providers_interactive(*, use_defaults: bool = False) -> None: function models_group (line 408) | def models_group() -> None: function list_cmd (line 413) | def list_cmd() -> None: function config_cmd (line 474) | def config_cmd() -> None: function config_key_cmd (line 481) | def config_key_cmd(provider_id: str | None) -> None: function set_llm_cmd (line 487) | def set_llm_cmd() -> None: function add_provider_cmd (line 497) | def add_provider_cmd( function remove_provider_cmd (line 538) | def remove_provider_cmd(provider_id: str, yes: bool) -> None: function add_model_cmd (line 569) | def add_model_cmd(provider_id: str, model_id: str, model_name: str) -> N... function remove_model_cmd (line 602) | def remove_model_cmd(provider_id: str, model_id: str) -> None: function download_cmd (line 659) | def download_cmd( function list_local_cmd (line 729) | def list_local_cmd(backend: str | None) -> None: function remove_local_cmd (line 764) | def remove_local_cmd(model_id: str, yes: bool) -> None: function ollama_pull_cmd (line 796) | def ollama_pull_cmd(model_name: str) -> None: function ollama_list_cmd (line 825) | def ollama_list_cmd() -> None: function ollama_remove_cmd (line 862) | def ollama_remove_cmd(model_name: str, yes: bool) -> None: FILE: src/copaw/cli/shutdown_cmd.py function _backend_port (line 27) | def _backend_port(ctx: click.Context, port: Optional[int]) -> int: function _listening_pids_for_port (line 34) | def _listening_pids_for_port(port: int) -> set[int]: function _find_frontend_dev_pids (line 90) | def _find_frontend_dev_pids() -> set[int]: function _find_desktop_wrapper_pids (line 109) | def _find_desktop_wrapper_pids() -> set[int]: function _find_windows_wrapper_ancestor_pids (line 124) | def _find_windows_wrapper_ancestor_pids(pids: set[int]) -> set[int]: function _child_pids_unix (line 155) | def _child_pids_unix(pid: int) -> set[int]: function _pid_exists (line 182) | def _pid_exists(pid: int) -> bool: function _wait_for_pid_exit (line 195) | def _wait_for_pid_exit( function _signal_process_tree_unix (line 209) | def _signal_process_tree_unix(pid: int, sig: signal.Signals) -> None: function _terminate_process_tree_windows (line 223) | def _terminate_process_tree_windows(pid: int, force: bool = False) -> None: function _force_terminate_windows_process (line 240) | def _force_terminate_windows_process(pid: int) -> None: function _terminate_pid (line 267) | def _terminate_pid(pid: int, timeout_sec: float = 5.0) -> bool: function _stop_pid_set (line 291) | def _stop_pid_set(pids: set[int]) -> tuple[list[int], list[int]]: function shutdown_cmd (line 311) | def shutdown_cmd(ctx: click.Context, port: Optional[int]) -> None: FILE: src/copaw/cli/skills_cmd.py function _get_agent_workspace (line 15) | def _get_agent_workspace(agent_id: str) -> Path: function configure_skills_interactive (line 29) | def configure_skills_interactive( function skills_group (line 128) | def skills_group() -> None: function list_cmd (line 138) | def list_cmd(agent_id: str) -> None: function configure_cmd (line 179) | def configure_cmd(agent_id: str) -> None: FILE: src/copaw/cli/uninstall_cmd.py function _remove_path_entry (line 25) | def _remove_path_entry(profile: Path) -> bool: function uninstall_cmd (line 53) | def uninstall_cmd(purge: bool, yes: bool) -> None: FILE: src/copaw/cli/update_cmd.py function _subprocess_text_kwargs (line 35) | def _subprocess_text_kwargs() -> dict[str, Any]: class InstallInfo (line 50) | class InstallInfo: class RunningServiceInfo (line 63) | class RunningServiceInfo: function _version_obj (line 71) | def _version_obj(version: str) -> Any: function _is_newer_version (line 79) | def _is_newer_version(latest: str, current: str) -> bool | None: function _fetch_latest_version (line 93) | def _fetch_latest_version() -> str: function _detect_source_type (line 120) | def _detect_source_type( function _detect_installation (line 138) | def _detect_installation() -> InstallInfo: function _probe_service (line 171) | def _probe_service(base_url: str) -> RunningServiceInfo: function _process_candidate_ports (line 193) | def _process_candidate_ports() -> list[int]: function _detect_running_service_from_processes (line 206) | def _detect_running_service_from_processes( function _detect_running_service (line 226) | def _detect_running_service( function _running_service_display (line 268) | def _running_service_display(running: RunningServiceInfo) -> str: function _confirm_force_shutdown (line 276) | def _confirm_force_shutdown(running: RunningServiceInfo) -> bool: function _run_shutdown_for_update (line 310) | def _run_shutdown_for_update( function _build_upgrade_command (line 348) | def _build_upgrade_command( function _plan_dir (line 383) | def _plan_dir() -> Path: function _write_worker_plan (line 388) | def _write_worker_plan(plan: dict[str, Any]) -> Path: function _spawn_update_worker (line 400) | def _spawn_update_worker( function _terminate_update_worker (line 436) | def _terminate_update_worker(proc: subprocess.Popen[str]) -> None: function _wait_for_process_exit (line 466) | def _wait_for_process_exit(pid: int | None, timeout: float = 15.0) -> None: function _run_update_worker_foreground (line 503) | def _run_update_worker_foreground(plan_path: Path) -> int: function _run_update_worker_detached (line 525) | def _run_update_worker_detached(plan_path: Path) -> None: function _load_worker_plan (line 535) | def _load_worker_plan(plan_path: str | Path) -> dict[str, Any]: function run_update_worker (line 540) | def run_update_worker(plan_path: str | Path) -> int: function _echo_install_summary (line 592) | def _echo_install_summary(info: InstallInfo, latest_version: str) -> None: function _confirm_source_override (line 605) | def _confirm_source_override(info: InstallInfo, yes: bool) -> bool: function update_cmd (line 638) | def update_cmd(ctx: click.Context, yes: bool) -> None: FILE: src/copaw/cli/utils.py function prompt_confirm (line 15) | def prompt_confirm(question: str, *, default: bool = False) -> bool: function prompt_path (line 44) | def prompt_path(label: str, *, default: str = "") -> str: function prompt_choice (line 70) | def prompt_choice( function prompt_select (line 110) | def prompt_select( function prompt_checkbox (line 151) | def prompt_checkbox( FILE: src/copaw/config/config.py function generate_short_agent_id (line 19) | def generate_short_agent_id() -> str: class BaseChannelConfig (line 28) | class BaseChannelConfig(BaseModel): class IMessageChannelConfig (line 42) | class IMessageChannelConfig(BaseChannelConfig): class DiscordConfig (line 51) | class DiscordConfig(BaseChannelConfig): class DingTalkConfig (line 57) | class DingTalkConfig(BaseChannelConfig): class FeishuConfig (line 67) | class FeishuConfig(BaseChannelConfig): class QQConfig (line 79) | class QQConfig(BaseChannelConfig): class TelegramConfig (line 85) | class TelegramConfig(BaseChannelConfig): class MQTTConfig (line 92) | class MQTTConfig(BaseChannelConfig): class MattermostConfig (line 108) | class MattermostConfig(BaseChannelConfig): class ConsoleConfig (line 118) | class ConsoleConfig(BaseChannelConfig): class WecomConfig (line 125) | class WecomConfig(BaseChannelConfig): class MatrixConfig (line 135) | class MatrixConfig(BaseChannelConfig): class VoiceChannelConfig (line 143) | class VoiceChannelConfig(BaseChannelConfig): class XiaoYiConfig (line 157) | class XiaoYiConfig(BaseChannelConfig): class ChannelConfig (line 167) | class ChannelConfig(BaseModel): class LastApiConfig (line 187) | class LastApiConfig(BaseModel): class ActiveHoursConfig (line 192) | class ActiveHoursConfig(BaseModel): class HeartbeatConfig (line 199) | class HeartbeatConfig(BaseModel): class AgentsDefaultsConfig (line 213) | class AgentsDefaultsConfig(BaseModel): class EmbeddingConfig (line 217) | class EmbeddingConfig(BaseModel): class AgentsRunningConfig (line 252) | class AgentsRunningConfig(BaseModel): method memory_compact_reserve (line 345) | def memory_compact_reserve(self) -> int: method memory_compact_threshold (line 350) | def memory_compact_threshold(self) -> int: class AgentsLLMRoutingConfig (line 355) | class AgentsLLMRoutingConfig(BaseModel): class AgentProfileRef (line 380) | class AgentProfileRef(BaseModel): class AgentProfileConfig (line 394) | class AgentProfileConfig(BaseModel): class AgentsConfig (line 455) | class AgentsConfig(BaseModel): class LastDispatchConfig (line 527) | class LastDispatchConfig(BaseModel): class MCPClientConfig (line 535) | class MCPClientConfig(BaseModel): method _normalize_legacy_fields (line 553) | def _normalize_legacy_fields(cls, data): method _validate_transport_config (line 593) | def _validate_transport_config(self): class MCPConfig (line 607) | class MCPConfig(BaseModel): class BuiltinToolConfig (line 628) | class BuiltinToolConfig(BaseModel): function _default_builtin_tools (line 640) | def _default_builtin_tools() -> Dict[str, BuiltinToolConfig]: class ToolsConfig (line 713) | class ToolsConfig(BaseModel): method _merge_default_tools (line 721) | def _merge_default_tools(self): class ToolGuardRuleConfig (line 729) | class ToolGuardRuleConfig(BaseModel): class ToolGuardConfig (line 743) | class ToolGuardConfig(BaseModel): class SkillScannerWhitelistEntry (line 757) | class SkillScannerWhitelistEntry(BaseModel): class SkillScannerConfig (line 772) | class SkillScannerConfig(BaseModel): class SecurityConfig (line 797) | class SecurityConfig(BaseModel): class Config (line 806) | class Config(BaseModel): function load_agent_config (line 844) | def load_agent_config(agent_id: str) -> AgentProfileConfig: function save_agent_config (line 931) | def save_agent_config( function migrate_legacy_config_to_multi_agent (line 966) | def migrate_legacy_config_to_multi_agent() -> bool: FILE: src/copaw/config/context.py function get_current_workspace_dir (line 18) | def get_current_workspace_dir() -> Path | None: function set_current_workspace_dir (line 27) | def set_current_workspace_dir(workspace_dir: Path | None) -> None: FILE: src/copaw/config/timezone.py function _is_iana (line 16) | def _is_iana(name: Optional[str]) -> bool: function detect_system_timezone (line 21) | def detect_system_timezone() -> str: function _detect_system_timezone_inner (line 33) | def _detect_system_timezone_inner() -> str: # noqa: R0911 function _probe_python (line 51) | def _probe_python() -> Optional[str]: function _probe_env (line 66) | def _probe_env() -> Optional[str]: function _probe_windows_registry (line 102) | def _probe_windows_registry() -> Optional[str]: function _probe_etc_timezone (line 119) | def _probe_etc_timezone() -> Optional[str]: function _probe_localtime_link (line 131) | def _probe_localtime_link() -> Optional[str]: function _probe_sysconfig_clock (line 142) | def _probe_sysconfig_clock() -> Optional[str]: function _probe_timedatectl (line 156) | def _probe_timedatectl() -> Optional[str]: FILE: src/copaw/config/utils.py function _normalize_working_dir_bound_paths (line 31) | def _normalize_working_dir_bound_paths(data: object) -> object: function _discover_system_chromium_path (line 67) | def _discover_system_chromium_path() -> Optional[str]: function get_playwright_chromium_executable_path (line 108) | def get_playwright_chromium_executable_path() -> Optional[str]: function _get_darwin_default_browser (line 168) | def _get_darwin_default_browser() -> Tuple[Optional[str], Optional[str]]: function _get_win32_default_browser (line 215) | def _get_win32_default_browser() -> Tuple[Optional[str], Optional[str]]: function _get_linux_default_browser (line 260) | def _get_linux_default_browser() -> Tuple[Optional[str], Optional[str]]: function _linux_desktop_to_kind_and_path (line 304) | def _linux_desktop_to_kind_and_path(exe_path: str) -> Tuple[str, str]: function get_system_default_browser (line 316) | def get_system_default_browser() -> Tuple[Optional[str], Optional[str]]: function get_available_channels (line 333) | def get_available_channels() -> Tuple[str, ...]: function is_running_in_container (line 361) | def is_running_in_container() -> bool: function get_config_path (line 378) | def get_config_path() -> Path: function get_heartbeat_query_path (line 383) | def get_heartbeat_query_path() -> Path: function _remove_nested_key (line 388) | def _remove_nested_key(data: dict, path: list) -> bool: function _remove_bad_field (line 413) | def _remove_bad_field(data: dict, loc: list) -> bool: function load_config (line 423) | def load_config(config_path: Optional[Path] = None) -> Config: function save_config (line 462) | def save_config(config: Config, config_path: Optional[Path] = None) -> N... function get_heartbeat_config (line 476) | def get_heartbeat_config(agent_id: Optional[str] = None) -> HeartbeatCon... function update_last_dispatch (line 502) | def update_last_dispatch( function read_last_api (line 539) | def read_last_api() -> Optional[Tuple[str, int]]: function write_last_api (line 549) | def write_last_api(host: str, port: int) -> None: function get_jobs_path (line 556) | def get_jobs_path() -> Path: function get_chats_path (line 562) | def get_chats_path() -> Path: FILE: src/copaw/constant.py class EnvVarLoader (line 12) | class EnvVarLoader: method get_bool (line 18) | def get_bool(env_var: str, default: bool = False) -> bool: method get_float (line 25) | def get_float( method get_int (line 49) | def get_int( method get_str (line 67) | def get_str(env_var: str, default: str = "") -> str: FILE: src/copaw/envs/store.py function _same_path (line 45) | def _same_path(a: Path, b: Path) -> bool: function _chmod_best_effort (line 52) | def _chmod_best_effort(path: Path, mode: int) -> None: function _prepare_secret_parent (line 60) | def _prepare_secret_parent(path: Path) -> None: function _migrate_legacy_envs_json (line 65) | def _migrate_legacy_envs_json(path: Path) -> None: function get_envs_json_path (line 103) | def get_envs_json_path() -> Path: function _apply_to_environ (line 113) | def _apply_to_environ( function _remove_from_environ (line 130) | def _remove_from_environ(key: str) -> None: function _sync_environ (line 135) | def _sync_environ( function load_envs (line 151) | def load_envs( function save_envs (line 182) | def save_envs( function set_env_var (line 203) | def set_env_var( function delete_env_var (line 214) | def delete_env_var(key: str) -> dict[str, str]: function load_envs_into_environ (line 222) | def load_envs_into_environ() -> dict[str, str]: FILE: src/copaw/local_models/backends/base.py class LocalBackend (line 12) | class LocalBackend(ABC): method __init__ (line 21) | def __init__(self, model_path: str, **kwargs: Any) -> None: method chat_completion (line 30) | def chat_completion( method chat_completion_stream (line 44) | def chat_completion_stream( method unload (line 57) | def unload(self) -> None: method is_loaded (line 62) | def is_loaded(self) -> bool: FILE: src/copaw/local_models/backends/llamacpp_backend.py function _normalize_messages (line 16) | def _normalize_messages(messages: list[dict]) -> list[dict]: class LlamaCppBackend (line 45) | class LlamaCppBackend(LocalBackend): method __init__ (line 48) | def __init__( method chat_completion (line 86) | def chat_completion( method chat_completion_stream (line 113) | def chat_completion_stream( method unload (line 131) | def unload(self) -> None: method is_loaded (line 138) | def is_loaded(self) -> bool: FILE: src/copaw/local_models/backends/mlx_backend.py function _normalize_messages (line 17) | def _normalize_messages(messages: list[dict]) -> list[dict]: function _resolve_model_dir (line 44) | def _resolve_model_dir(model_path: str) -> str: class MlxBackend (line 57) | class MlxBackend(LocalBackend): method __init__ (line 60) | def __init__( method _build_prompt (line 84) | def _build_prompt( method chat_completion (line 98) | def chat_completion( method chat_completion_stream (line 175) | def chat_completion_stream( method unload (line 225) | def unload(self) -> None: method is_loaded (line 234) | def is_loaded(self) -> bool: FILE: src/copaw/local_models/chat_model.py function _json_loads_safe (line 31) | def _json_loads_safe(s: str) -> dict: class LocalChatModel (line 39) | class LocalChatModel(ChatModelBase): method __init__ (line 47) | def __init__( method __call__ (line 58) | async def __call__( method _stream_response (line 96) | async def _stream_response( method _parse_completion_response (line 259) | def _parse_completion_response( FILE: src/copaw/local_models/factory.py function get_active_local_model (line 22) | def get_active_local_model() -> ( function unload_active_model (line 32) | def unload_active_model() -> None: function create_local_chat_model (line 42) | def create_local_chat_model( function _create_backend (line 110) | def _create_backend( FILE: src/copaw/local_models/manager.py function _ensure_models_dir (line 25) | def _ensure_models_dir() -> Path: function _load_manifest (line 30) | def _load_manifest() -> LocalModelsManifest: function _save_manifest (line 40) | def _save_manifest(manifest: LocalModelsManifest) -> None: function list_local_models (line 52) | def list_local_models( function get_local_model (line 63) | def get_local_model(model_id: str) -> Optional[LocalModelInfo]: function delete_local_model (line 69) | def delete_local_model(model_id: str) -> None: function _sanitize_repo_id (line 89) | def _sanitize_repo_id(repo_id: str) -> str: class LocalModelManager (line 94) | class LocalModelManager: method download_model_sync (line 98) | def download_model_sync( method _download_from_huggingface (line 125) | def _download_from_huggingface( method _download_from_modelscope (line 188) | def _download_from_modelscope( method _auto_select_file (line 295) | def _auto_select_file( method _validate_mlx_directory (line 332) | def _validate_mlx_directory(model_dir: Path) -> None: method _register_model (line 364) | def _register_model( FILE: src/copaw/local_models/schema.py class BackendType (line 12) | class BackendType(str, Enum): class DownloadSource (line 17) | class DownloadSource(str, Enum): class LocalModelInfo (line 22) | class LocalModelInfo(BaseModel): class DownloadProgress (line 44) | class DownloadProgress(BaseModel): class LocalModelsManifest (line 55) | class LocalModelsManifest(BaseModel): FILE: src/copaw/local_models/tag_parser.py class TextWithThinking (line 47) | class TextWithThinking: class ParsedToolCall (line 60) | class ParsedToolCall: class TextWithToolCalls (line 70) | class TextWithToolCalls: function _generate_call_id (line 91) | def _generate_call_id() -> str: function _parse_single_tool_call (line 95) | def _parse_single_tool_call(raw_text: str) -> ParsedToolCall | None: function text_contains_think_tag (line 134) | def text_contains_think_tag(text: str) -> bool: function extract_thinking_from_text (line 139) | def extract_thinking_from_text(text: str) -> TextWithThinking: function text_contains_tool_call_tag (line 171) | def text_contains_tool_call_tag(text: str) -> bool: function parse_tool_calls_from_text (line 176) | def parse_tool_calls_from_text(text: str) -> TextWithToolCalls: FILE: src/copaw/providers/anthropic_provider.py class AnthropicProvider (line 18) | class AnthropicProvider(Provider): method _client (line 21) | def _client(self, timeout: float = 5) -> anthropic.AsyncAnthropic: method _normalize_models_payload (line 29) | def _normalize_models_payload(payload: Any) -> List[ModelInfo]: method check_connection (line 57) | async def check_connection(self, timeout: float = 5) -> tuple[bool, str]: method fetch_models (line 71) | async def fetch_models(self, timeout: float = 5) -> List[ModelInfo]: method check_model_connection (line 78) | async def check_model_connection( method get_chat_model_instance (line 119) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: FILE: src/copaw/providers/gemini_provider.py class GeminiProvider (line 17) | class GeminiProvider(Provider): method _client (line 20) | def _client(self, timeout: float = 10) -> Any: method _normalize_models_payload (line 27) | def _normalize_models_payload(payload: Any) -> List[ModelInfo]: method check_connection (line 58) | async def check_connection(self, timeout: float = 10) -> tuple[bool, s... method fetch_models (line 78) | async def fetch_models(self, timeout: float = 10) -> List[ModelInfo]: method check_model_connection (line 92) | async def check_model_connection( method get_chat_model_instance (line 122) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: FILE: src/copaw/providers/models.py class ModelInfo (line 11) | class ModelInfo(BaseModel): class ProviderDefinition (line 16) | class ProviderDefinition(BaseModel): class ProviderSettings (line 41) | class ProviderSettings(BaseModel): class CustomProviderData (line 54) | class CustomProviderData(BaseModel): class ModelSlotConfig (line 74) | class ModelSlotConfig(BaseModel): class ActiveModelsInfo (line 79) | class ActiveModelsInfo(BaseModel): FILE: src/copaw/providers/ollama_manager.py class OllamaModelInfo (line 21) | class OllamaModelInfo(BaseModel): method convert_datetime_to_str (line 34) | def convert_datetime_to_str( function _ensure_ollama (line 46) | def _ensure_ollama(): function _base_url_to_host (line 61) | def _base_url_to_host(base_url: str) -> Optional[str]: class OllamaModelManager (line 75) | class OllamaModelManager: method _make_client (line 87) | def _make_client(host: Optional[str] = None): method list_models (line 96) | def list_models(host: Optional[str] = None) -> List[OllamaModelInfo]: method pull_model (line 113) | def pull_model( method delete_model (line 134) | def delete_model(name: str, host: Optional[str] = None) -> None: FILE: src/copaw/providers/ollama_provider.py class OllamaProvider (line 19) | class OllamaProvider(Provider): method model_post_init (line 22) | def model_post_init(self, __context: Any) -> None: method _client (line 32) | def _client(self, timeout: float = 5): method _normalize_models_payload (line 43) | def _normalize_models_payload(payload: Any) -> List[ModelInfo]: method check_connection (line 69) | async def check_connection(self, timeout: float = 5) -> tuple[bool, str]: method fetch_models (line 85) | async def fetch_models(self, timeout: float = 5) -> List[ModelInfo]: method check_model_connection (line 95) | async def check_model_connection( method add_model (line 119) | async def add_model( method delete_model (line 146) | async def delete_model( method get_chat_model_instance (line 163) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: FILE: src/copaw/providers/openai_chat_model_compat.py function _clone_with_overrides (line 16) | def _clone_with_overrides(obj: Any, **overrides: Any) -> Any: function _sanitize_tool_call (line 23) | def _sanitize_tool_call(tool_call: Any) -> Any | None: function _sanitize_chunk (line 72) | def _sanitize_chunk(chunk: Any) -> Any: function _sanitize_stream_item (line 121) | def _sanitize_stream_item(item: Any) -> Any: class _SanitizedStream (line 133) | class _SanitizedStream: method __init__ (line 138) | def __init__(self, stream: Any): method __aenter__ (line 143) | async def __aenter__(self) -> "_SanitizedStream": method __aexit__ (line 147) | async def __aexit__( method __aiter__ (line 155) | def __aiter__(self) -> "_SanitizedStream": method __anext__ (line 158) | async def __anext__(self) -> Any: method _capture_extra_content (line 165) | def _capture_extra_content(self, item: Any) -> None: class OpenAIChatModelCompat (line 186) | class OpenAIChatModelCompat(OpenAIChatModel): method _parse_openai_stream_response (line 190) | async def _parse_openai_stream_response( FILE: src/copaw/providers/openai_provider.py class OpenAIProvider (line 18) | class OpenAIProvider(Provider): method _client (line 21) | def _client(self, timeout: float = 5) -> AsyncOpenAI: method _normalize_models_payload (line 29) | def _normalize_models_payload(payload: Any) -> List[ModelInfo]: method check_connection (line 50) | async def check_connection(self, timeout: float = 5) -> tuple[bool, str]: method fetch_models (line 66) | async def fetch_models(self, timeout: float = 5) -> List[ModelInfo]: method check_model_connection (line 78) | async def check_model_connection( method get_chat_model_instance (line 119) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: FILE: src/copaw/providers/provider.py class ModelInfo (line 11) | class ModelInfo(BaseModel): class ProviderInfo (line 16) | class ProviderInfo(BaseModel): class Provider (line 73) | class Provider(ProviderInfo, ABC): method check_connection (line 77) | async def check_connection(self, timeout: float = 5) -> tuple[bool, str]: method fetch_models (line 81) | async def fetch_models(self, timeout: float = 5) -> List[ModelInfo]: method check_model_connection (line 85) | async def check_model_connection( method add_model (line 92) | async def add_model( method delete_model (line 111) | async def delete_model( method update_config (line 122) | def update_config(self, config: Dict) -> None: method get_chat_model_cls (line 149) | def get_chat_model_cls(self) -> Type[ChatModelBase]: method has_model (line 165) | def has_model(self, model_id: str) -> bool: method get_chat_model_instance (line 172) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: method get_info (line 176) | async def get_info(self, mock_secret: bool = True) -> ProviderInfo: class DefaultProvider (line 204) | class DefaultProvider(Provider): method check_connection (line 207) | async def check_connection(self, timeout: float = 5) -> tuple[bool, str]: method fetch_models (line 212) | async def fetch_models(self, timeout: float = 5) -> List[ModelInfo]: method check_model_connection (line 215) | async def check_model_connection( method update_config (line 224) | def update_config(self, config: Dict) -> None: method get_chat_model_instance (line 227) | def get_chat_model_instance(self, model_id: str) -> ChatModelBase: FILE: src/copaw/providers/provider_manager.py class ActiveModelsInfo (line 284) | class ActiveModelsInfo(BaseModel): class ProviderManager (line 288) | class ProviderManager: method __init__ (line 294) | def __init__(self) -> None: method _prepare_disk_storage (line 312) | def _prepare_disk_storage(self): method _init_builtins (line 321) | def _init_builtins(self): method _add_builtin (line 339) | def _add_builtin(self, provider: Provider): method list_provider_info (line 342) | async def list_provider_info(self) -> List[ProviderInfo]: method get_provider (line 352) | def get_provider(self, provider_id: str) -> Provider | None: method get_provider_info (line 361) | async def get_provider_info(self, provider_id: str) -> ProviderInfo | ... method get_active_model (line 365) | def get_active_model(self) -> ModelSlotConfig | None: method update_provider (line 369) | def update_provider(self, provider_id: str, config: Dict) -> bool: method fetch_provider_models (line 384) | async def fetch_provider_models( method _resolve_custom_provider_id (line 408) | def _resolve_custom_provider_id(self, provider_id: str) -> str: method add_custom_provider (line 423) | async def add_custom_provider(self, provider_data: ProviderInfo): method remove_custom_provider (line 441) | def remove_custom_provider(self, provider_id: str) -> bool: method activate_model (line 452) | async def activate_model(self, provider_id: str, model_id: str): method add_model_to_provider (line 469) | async def add_model_to_provider( method delete_model_from_provider (line 484) | async def delete_model_from_provider( method _save_provider (line 499) | def _save_provider( method load_provider (line 517) | def load_provider( method _provider_from_data (line 540) | def _provider_from_data(self, data: Dict) -> Provider: method save_active_model (line 555) | def save_active_model(self, active_model: ModelSlotConfig): method load_active_model (line 570) | def load_active_model(self) -> ModelSlotConfig | None: method _migrate_legacy_providers (line 582) | def _migrate_legacy_providers(self): method _init_from_storage (line 648) | def _init_from_storage(self): method update_local_models (line 670) | def update_local_models(self): method get_instance (line 692) | def get_instance() -> "ProviderManager": method get_active_chat_model (line 699) | def get_active_chat_model() -> ChatModelBase: FILE: src/copaw/providers/retry_chat_model.py function _get_openai_retryable (line 32) | def _get_openai_retryable() -> tuple[type[Exception], ...]: function _get_anthropic_retryable (line 48) | def _get_anthropic_retryable() -> tuple[type[Exception], ...]: function _is_retryable (line 64) | def _is_retryable(exc: Exception) -> bool: function _compute_backoff (line 77) | def _compute_backoff(attempt: int) -> float: class RetryChatModel (line 82) | class RetryChatModel(ChatModelBase): method __init__ (line 91) | def __init__(self, inner: ChatModelBase) -> None: method inner_class (line 98) | def inner_class(self) -> type: method __call__ (line 101) | async def __call__( method _wrap_stream (line 142) | async def _wrap_stream( FILE: src/copaw/security/skill_scanner/__init__.py function _load_scanner_config (line 85) | def _load_scanner_config() -> Any: function _get_scan_mode (line 95) | def _get_scan_mode(cfg: Any = None) -> str: function _scan_timeout (line 110) | def _scan_timeout(cfg: Any = None) -> float: function compute_skill_content_hash (line 121) | def compute_skill_content_hash(skill_dir: Path) -> str: function is_skill_whitelisted (line 141) | def is_skill_whitelisted( function _get_blocked_history_path (line 178) | def _get_blocked_history_path() -> Path: class BlockedSkillRecord (line 188) | class BlockedSkillRecord: method to_dict (line 198) | def to_dict(self) -> dict[str, Any]: method from_dict (line 209) | def from_dict(cls, data: dict[str, Any]) -> BlockedSkillRecord: function _finding_to_dict (line 220) | def _finding_to_dict(f: Finding) -> dict[str, Any]: function _record_blocked_skill (line 231) | def _record_blocked_skill( function get_blocked_history (line 262) | def get_blocked_history() -> list[BlockedSkillRecord]: function clear_blocked_history (line 275) | def clear_blocked_history() -> None: function remove_blocked_entry (line 285) | def remove_blocked_entry(index: int) -> bool: function _get_scanner (line 313) | def _get_scanner() -> SkillScanner: function _get_dir_mtime (line 332) | def _get_dir_mtime(skill_dir: Path) -> float: function _get_cached_result (line 347) | def _get_cached_result( function _store_cached_result (line 367) | def _store_cached_result( function _format_finding_location (line 387) | def _format_finding_location(f: Finding) -> str: class SkillScanError (line 393) | class SkillScanError(Exception): method __init__ (line 396) | def __init__(self, result: ScanResult) -> None: function scan_skill_directory (line 415) | def scan_skill_directory( FILE: src/copaw/security/skill_scanner/analyzers/__init__.py class BaseAnalyzer (line 21) | class BaseAnalyzer(ABC): method __init__ (line 34) | def __init__( method policy (line 49) | def policy(self) -> "ScanPolicy": method analyze (line 58) | def analyze( method get_name (line 87) | def get_name(self) -> str: # noqa: D401 FILE: src/copaw/security/skill_scanner/analyzers/pattern_analyzer.py class SecurityRule (line 38) | class SecurityRule: method __init__ (line 54) | def __init__(self, rule_data: dict[str, Any]) -> None: method matches_file_type (line 87) | def matches_file_type(self, file_type: str) -> bool: method scan_content (line 93) | def scan_content( class RuleLoader (line 163) | class RuleLoader: method __init__ (line 166) | def __init__(self, rules_path: Path | None = None) -> None: method load_rules (line 172) | def load_rules(self) -> list[SecurityRule]: method get_rule (line 218) | def get_rule(self, rule_id: str) -> SecurityRule | None: method get_rules_for_file_type (line 221) | def get_rules_for_file_type(self, file_type: str) -> list[SecurityRule]: method get_rules_for_category (line 224) | def get_rules_for_category( class PatternAnalyzer (line 236) | class PatternAnalyzer(BaseAnalyzer): method __init__ (line 249) | def __init__( method analyze (line 265) | def analyze( method _is_known_test_credential (line 353) | def _is_known_test_credential(self, finding: Finding) -> bool: method _dedupe_findings (line 371) | def _dedupe_findings(findings: list[Finding]) -> list[Finding]: method _get_rules (line 386) | def _get_rules(self, file_type: str) -> list[SecurityRule]: FILE: src/copaw/security/skill_scanner/models.py class Severity (line 19) | class Severity(str, Enum): class ThreatCategory (line 30) | class ThreatCategory(str, Enum): class SkillFile (line 77) | class SkillFile: method read_content (line 86) | def read_content(self) -> str: method is_hidden (line 97) | def is_hidden(self) -> bool: method from_path (line 107) | def from_path(cls, path: Path, base_dir: Path) -> "SkillFile": class Finding (line 130) | class Finding: method to_dict (line 146) | def to_dict(self) -> dict[str, Any]: class ScanResult (line 169) | class ScanResult: method is_safe (line 187) | def is_safe(self) -> bool: method max_severity (line 195) | def max_severity(self) -> Severity: method get_findings_by_severity (line 211) | def get_findings_by_severity(self, severity: Severity) -> list[Finding]: method get_findings_by_category (line 214) | def get_findings_by_category( method to_dict (line 220) | def to_dict(self) -> dict[str, Any]: FILE: src/copaw/security/skill_scanner/scan_policy.py function _safe_compile (line 49) | def _safe_compile( class HiddenFilePolicy (line 75) | class HiddenFilePolicy: class RuleScopingPolicy (line 83) | class RuleScopingPolicy: class CredentialPolicy (line 101) | class CredentialPolicy: class FileClassificationPolicy (line 109) | class FileClassificationPolicy: class FileLimitsPolicy (line 123) | class FileLimitsPolicy: class AnalysisThresholdsPolicy (line 135) | class AnalysisThresholdsPolicy: class SeverityOverride (line 143) | class SeverityOverride: class ScanPolicy (line 157) | class ScanPolicy: method get_severity_override (line 183) | def get_severity_override(self, rule_id: str) -> str | None: method is_rule_disabled (line 190) | def is_rule_disabled(self, rule_id: str) -> bool: method is_doc_path (line 194) | def is_doc_path(self, rel_path: str) -> bool: method _compiled_doc_filename_re (line 206) | def _compiled_doc_filename_re(self) -> re.Pattern | None: method default (line 237) | def default(cls) -> ScanPolicy: method from_preset (line 245) | def from_preset(cls, name: str) -> ScanPolicy: method preset_names (line 256) | def preset_names(cls) -> list[str]: method from_yaml (line 261) | def from_yaml(cls, path: str | Path) -> ScanPolicy: method to_yaml (line 283) | def to_yaml(self, path: str | Path) -> None: method _load_default_raw (line 310) | def _load_default_raw(cls) -> dict[str, Any]: method _deep_merge (line 317) | def _deep_merge(base: dict, override: dict) -> dict: method _from_dict (line 337) | def _from_dict(cls, d: dict[str, Any]) -> ScanPolicy: method _to_dict (line 399) | def _to_dict(self) -> dict[str, Any]: FILE: src/copaw/security/skill_scanner/scanner.py class SkillScanner (line 76) | class SkillScanner: method __init__ (line 100) | def __init__( method policy (line 136) | def policy(self) -> ScanPolicy: method register_analyzer (line 144) | def register_analyzer(self, analyzer: BaseAnalyzer) -> None: method scan_skill (line 148) | def scan_skill( method _discover_files (line 248) | def _discover_files(self, skill_dir: Path) -> list[SkillFile]: method _default_analyzers (line 306) | def _default_analyzers( FILE: src/copaw/security/tool_guard/approval.py class ApprovalDecision (line 12) | class ApprovalDecision(str, Enum): function format_findings_summary (line 20) | def format_findings_summary( FILE: src/copaw/security/tool_guard/engine.py function _guard_enabled (line 34) | def _guard_enabled() -> bool: class ToolGuardEngine (line 52) | class ToolGuardEngine: method __init__ (line 64) | def __init__( method _default_guardians (line 84) | def _default_guardians() -> list[BaseToolGuardian]: method register_guardian (line 100) | def register_guardian(self, guardian: BaseToolGuardian) -> None: method unregister_guardian (line 105) | def unregister_guardian(self, name: str) -> bool: method guardian_names (line 112) | def guardian_names(self) -> list[str]: method enabled (line 116) | def enabled(self) -> bool: method enabled (line 120) | def enabled(self, value: bool) -> None: method guarded_tools (line 124) | def guarded_tools(self) -> set[str] | None: method denied_tools (line 129) | def denied_tools(self) -> set[str]: method _reload_tool_sets (line 133) | def _reload_tool_sets(self) -> None: method reload_rules (line 140) | def reload_rules(self) -> None: method is_denied (line 147) | def is_denied(self, tool_name: str) -> bool: method is_guarded (line 151) | def is_guarded(self, tool_name: str) -> bool: method guard (line 161) | def guard( function get_guard_engine (line 212) | def get_guard_engine() -> ToolGuardEngine: FILE: src/copaw/security/tool_guard/guardians/__init__.py class BaseToolGuardian (line 17) | class BaseToolGuardian(ABC): method __init__ (line 26) | def __init__(self, name: str) -> None: method guard (line 34) | def guard( method __repr__ (line 59) | def __repr__(self) -> str: FILE: src/copaw/security/tool_guard/guardians/rule_guardian.py class GuardRule (line 52) | class GuardRule: method __init__ (line 69) | def __init__(self, rule_data: dict[str, Any]) -> None: method applies_to_tool (line 119) | def applies_to_tool(self, tool_name: str) -> bool: method applies_to_param (line 125) | def applies_to_param(self, param_name: str) -> bool: method match (line 131) | def match(self, value: str) -> tuple[re.Match[str] | None, str | None]: function load_rules_from_yaml (line 153) | def load_rules_from_yaml(yaml_path: Path) -> list[GuardRule]: function load_rules_from_directory (line 188) | def load_rules_from_directory( function _load_config_rules (line 239) | def _load_config_rules() -> tuple[list[GuardRule], set[str]]: class RuleBasedToolGuardian (line 280) | class RuleBasedToolGuardian(BaseToolGuardian): method __init__ (line 292) | def __init__( method _load_all_rules (line 304) | def _load_all_rules(self) -> None: method reload (line 311) | def reload(self) -> None: method rules (line 317) | def rules(self) -> list[GuardRule]: method rule_count (line 322) | def rule_count(self) -> int: method guard (line 329) | def guard( FILE: src/copaw/security/tool_guard/models.py class GuardSeverity (line 25) | class GuardSeverity(str, Enum): class GuardThreatCategory (line 36) | class GuardThreatCategory(str, Enum): class GuardFinding (line 61) | class GuardFinding: method to_dict (line 79) | def to_dict(self) -> dict[str, Any]: class ToolGuardResult (line 104) | class ToolGuardResult: method is_safe (line 122) | def is_safe(self) -> bool: method max_severity (line 130) | def max_severity(self) -> GuardSeverity: method findings_count (line 147) | def findings_count(self) -> int: method get_findings_by_severity (line 150) | def get_findings_by_severity( method get_findings_by_category (line 156) | def get_findings_by_category( method to_dict (line 162) | def to_dict(self) -> dict[str, Any]: function _safe_repr (line 179) | def _safe_repr(value: Any, max_len: int = 200) -> str: FILE: src/copaw/security/tool_guard/utils.py function _parse_guarded_tokens (line 25) | def _parse_guarded_tokens(tokens: Iterable[str]) -> set[str] | None: function _load_config_tool_guard (line 43) | def _load_config_tool_guard(): function resolve_guarded_tools (line 56) | def resolve_guarded_tools( function resolve_denied_tools (line 91) | def resolve_denied_tools( function log_findings (line 121) | def log_findings(tool_name: str, result: "ToolGuardResult") -> None: FILE: src/copaw/token_usage/manager.py class TokenUsageStats (line 19) | class TokenUsageStats(BaseModel): class TokenUsageRecord (line 27) | class TokenUsageRecord(TokenUsageStats): class TokenUsageByModel (line 35) | class TokenUsageByModel(TokenUsageStats): class TokenUsageSummary (line 42) | class TokenUsageSummary(BaseModel): class TokenUsageManager (line 62) | class TokenUsageManager: method __init__ (line 69) | def __init__(self) -> None: method _load_data (line 73) | async def _load_data(self) -> dict: method _save_data (line 93) | async def _save_data(self, data: dict) -> None: method record (line 110) | async def record( method _query (line 157) | async def _query( method get_summary (line 198) | async def get_summary( method get_instance (line 297) | def get_instance(cls) -> "TokenUsageManager": function get_token_usage_manager (line 306) | def get_token_usage_manager() -> TokenUsageManager: FILE: src/copaw/token_usage/model_wrapper.py class TokenRecordingModelWrapper (line 15) | class TokenRecordingModelWrapper(ChatModelBase): method __init__ (line 18) | def __init__(self, provider_id: str, model: ChatModelBase) -> None: method _record_usage (line 26) | async def _record_usage(self, usage: ChatUsage | None) -> None: method __call__ (line 40) | async def __call__( method _wrap_stream (line 61) | async def _wrap_stream( FILE: src/copaw/tunnel/binary_manager.py function _platform_key (line 65) | def _platform_key() -> tuple[str, str]: function _download_file (line 69) | async def _download_file( class BinaryManager (line 91) | class BinaryManager: method __init__ (line 94) | def __init__(self, bin_dir: Path | None = None) -> None: method get_binary_path (line 97) | async def get_binary_path(self) -> str: method _verify_checksum (line 115) | def _verify_checksum(path: str, expected: str) -> None: method _download (line 129) | async def _download(self) -> str: FILE: src/copaw/tunnel/cloudflare.py class TunnelInfo (line 25) | class TunnelInfo: class CloudflareTunnelDriver (line 34) | class CloudflareTunnelDriver: method __init__ (line 46) | def __init__(self, binary_manager: BinaryManager | None = None) -> None: method start (line 52) | async def start(self, local_port: int) -> TunnelInfo: method stop (line 99) | async def stop(self) -> None: method health_check (line 120) | async def health_check(self) -> bool: method get_public_url (line 124) | def get_public_url(self) -> str | None: method get_info (line 128) | def get_info(self) -> TunnelInfo | None: method _wait_for_url (line 132) | async def _wait_for_url(self, timeout: float = 30) -> str | None: method _drain_stderr (line 160) | async def _drain_stderr(self) -> None: method _monitor (line 173) | async def _monitor(self) -> None: FILE: src/copaw/utils/telemetry.py function _safe_get (line 21) | def _safe_get(func: Callable[[], str], default: str = "unknown") -> str: function _detect_install_method (line 29) | def _detect_install_method() -> str: function get_system_info (line 48) | def get_system_info() -> dict[str, Any]: function _detect_gpu (line 78) | def _detect_gpu() -> bool | str: function _upload_telemetry_sync (line 163) | def _upload_telemetry_sync(data: dict[str, Any]) -> bool: function _get_current_version (line 184) | def _get_current_version() -> str: function has_telemetry_been_collected (line 194) | def has_telemetry_been_collected(working_dir: Path) -> bool: function is_telemetry_opted_out (line 222) | def is_telemetry_opted_out(working_dir: Path) -> bool: function mark_telemetry_collected (line 243) | def mark_telemetry_collected( function collect_and_upload_telemetry (line 292) | def collect_and_upload_telemetry(working_dir: Path) -> bool: FILE: tests/integrated/test_app_startup.py function _find_free_port (line 15) | def _find_free_port(host: str = "127.0.0.1") -> int: function _tee_stream (line 23) | def _tee_stream(stream, buffer: list[str]) -> None: function test_app_startup_and_console (line 33) | def test_app_startup_and_console() -> None: FILE: tests/integrated/test_version.py function test_version_import (line 12) | def test_version_import() -> None: function test_version_pep440_compliant (line 21) | def test_version_pep440_compliant() -> None: function test_version_via_subprocess (line 32) | def test_version_via_subprocess() -> None: FILE: tests/unit/channels/test_qq_channel.py function _make_channel (line 47) | def _make_channel(**overrides: Any) -> QQChannel: class TestSanitizeQQText (line 72) | class TestSanitizeQQText: method test_empty_string (line 73) | def test_empty_string(self): method test_no_url (line 76) | def test_no_url(self): method test_single_url (line 79) | def test_single_url(self): method test_multiple_urls (line 85) | def test_multiple_urls(self): class TestAsBool (line 93) | class TestAsBool: method test_values (line 112) | def test_values(self, val, expected): class TestShouldPlaintextFallback (line 116) | class TestShouldPlaintextFallback: method test_non_qq_api_error (line 117) | def test_non_qq_api_error(self): method test_server_error_status (line 125) | def test_server_error_status(self): method test_status_below_400 (line 129) | def test_status_below_400(self): method test_markdown_in_data (line 133) | def test_markdown_in_data(self): method test_msg_type_in_data (line 137) | def test_msg_type_in_data(self): method test_no_markdown_keyword (line 141) | def test_no_markdown_keyword(self): class TestGetNextMsgSeq (line 146) | class TestGetNextMsgSeq: method test_increments (line 147) | def test_increments(self): class TestMediaPath (line 154) | class TestMediaPath: method test_c2c (line 155) | def test_c2c(self): method test_group (line 160) | def test_group(self): method test_unsupported (line 165) | def test_unsupported(self): class TestQQApiError (line 169) | class TestQQApiError: method test_attributes (line 170) | def test_attributes(self): class TestWSState (line 183) | class TestWSState: method test_defaults (line 184) | def test_defaults(self): method test_mutable (line 193) | def test_mutable(self): class TestMessageEventSpecs (line 206) | class TestMessageEventSpecs: method test_all_four_types_present (line 207) | def test_all_four_types_present(self): method test_c2c_spec (line 216) | def test_c2c_spec(self): method test_guild_spec (line 222) | def test_guild_spec(self): method test_group_spec (line 228) | def test_group_spec(self): class TestHeartbeatController (line 239) | class TestHeartbeatController: method test_start_and_stop (line 240) | def test_start_and_stop(self): method test_stop_when_no_timer (line 250) | def test_stop_when_no_timer(self): method test_no_schedule_when_stopped (line 255) | def test_no_schedule_when_stopped(self): class TestComputeReconnectDelay (line 270) | class TestComputeReconnectDelay: method test_first_attempt (line 271) | def test_first_attempt(self): method test_escalating_delay (line 277) | def test_escalating_delay(self): method test_max_delay_clamped (line 283) | def test_max_delay_clamped(self): method test_quick_disconnect_triggers_rate_limit (line 289) | def test_quick_disconnect_triggers_rate_limit(self): method test_normal_disconnect_resets_quick_count (line 300) | def test_normal_disconnect_resets_quick_count(self): class TestHandleWsPayload (line 315) | class TestHandleWsPayload: method _make_deps (line 316) | def _make_deps(self): method test_hello_sends_identify (line 323) | def test_hello_sends_identify(self): method test_hello_sends_resume_when_session_exists (line 338) | def test_hello_sends_resume_when_session_exists(self): method test_dispatch_ready (line 355) | def test_dispatch_ready(self): method test_dispatch_message_calls_handle_msg_event (line 368) | def test_dispatch_message_calls_handle_msg_event(self): method test_heartbeat_ack (line 384) | def test_heartbeat_ack(self): method test_reconnect_returns_break (line 390) | def test_reconnect_returns_break(self): method test_invalid_session_not_resumable (line 396) | def test_invalid_session_not_resumable(self): method test_invalid_session_resumable (line 407) | def test_invalid_session_resumable(self): method test_seq_updated (line 418) | def test_seq_updated(self): method test_unknown_op (line 424) | def test_unknown_op(self): class TestHandleMsgEvent (line 436) | class TestHandleMsgEvent: method test_c2c_message_enqueues (line 437) | def test_c2c_message_enqueues(self): method test_guild_message_has_extra_meta (line 453) | def test_guild_message_has_extra_meta(self): method test_group_message (line 471) | def test_group_message(self): method test_empty_text_no_attachments_skipped (line 487) | def test_empty_text_no_attachments_skipped(self): method test_bot_prefix_skipped (line 495) | def test_bot_prefix_skipped(self): method test_no_sender_skipped (line 507) | def test_no_sender_skipped(self): method test_unknown_event_type_ignored (line 515) | def test_unknown_event_type_ignored(self): method test_sender_fallback_to_second_key (line 522) | def test_sender_fallback_to_second_key(self): class TestResolveSendPath (line 542) | class TestResolveSendPath: method test_c2c (line 543) | def test_c2c(self): method test_group (line 555) | def test_group(self): method test_guild (line 567) | def test_guild(self): method test_fallback_to_c2c (line 578) | def test_fallback_to_c2c(self): class TestResolveAttachmentType (line 595) | class TestResolveAttachmentType: method test_by_extension (line 596) | def test_by_extension(self): method test_direct_type (line 603) | def test_direct_type(self): method test_voice_maps_to_audio (line 610) | def test_voice_maps_to_audio(self): method test_mime_type (line 614) | def test_mime_type(self): method test_unknown_mime (line 626) | def test_unknown_mime(self): class TestMakeContentPart (line 642) | class TestMakeContentPart: method test_image (line 643) | def test_image(self): method test_video (line 648) | def test_video(self): method test_audio (line 653) | def test_audio(self): method test_file (line 658) | def test_file(self): method test_unknown_returns_none (line 664) | def test_unknown_returns_none(self): class TestSend (line 673) | class TestSend: method test_disabled_channel_noop (line 674) | async def test_disabled_channel_noop(self): method test_empty_text_noop (line 680) | async def test_empty_text_noop(self): method test_to_handle_group_prefix (line 686) | async def test_to_handle_group_prefix(self): method test_to_handle_channel_prefix (line 696) | async def test_to_handle_channel_prefix(self): method test_image_tags_extracted (line 706) | async def test_image_tags_extracted(self): method test_token_failure_handled (line 721) | async def test_token_failure_handled(self): class TestSendTextWithFallback (line 737) | class TestSendTextWithFallback: method test_success (line 738) | async def test_success(self): method test_markdown_fallback_on_validation_error (line 754) | async def test_markdown_fallback_on_validation_error(self): method test_no_fallback_on_non_markdown_error (line 781) | async def test_no_fallback_on_non_markdown_error(self): method test_plain_text_failure (line 800) | async def test_plain_text_failure(self): class TestSendImages (line 823) | class TestSendImages: method test_no_images_noop (line 824) | async def test_no_images_noop(self): method test_unsupported_type_noop (line 829) | async def test_unsupported_type_noop(self): method test_upload_and_send (line 849) | async def test_upload_and_send(self, mock_send_media, mock_upload): method test_upload_failure_skips (line 867) | async def test_upload_failure_skips(self, mock_upload): class TestSendMessageAsync (line 886) | class TestSendMessageAsync: method test_plain_text (line 891) | async def test_plain_text(self, mock_api): method test_markdown (line 914) | async def test_markdown(self, mock_api): method test_channel_no_msg_seq (line 934) | async def test_channel_no_msg_seq(self, mock_api): class TestBuildAgentRequestFromNative (line 953) | class TestBuildAgentRequestFromNative: method test_basic_request (line 954) | def test_basic_request(self): method test_non_dict_payload (line 967) | def test_non_dict_payload(self): method test_with_attachments (line 973) | def test_with_attachments(self): class TestLifecycle (line 993) | class TestLifecycle: method test_start_disabled (line 994) | async def test_start_disabled(self): method test_start_missing_credentials (line 999) | async def test_start_missing_credentials(self): method test_stop_disabled_noop (line 1004) | async def test_stop_disabled_noop(self): FILE: tests/unit/cli/test_cli_version.py function test_cli_version_option_outputs_current_version (line 8) | def test_cli_version_option_outputs_current_version() -> None: