diff --git a/hello/RDMind.md b/hello/RDMind.md new file mode 100644 index 00000000..22f6bbce --- /dev/null +++ b/hello/RDMind.md @@ -0,0 +1,8 @@ +# Ink Library Screen Reader Guidance + +When building custom components, it's important to keep accessibility in mind. While Ink provides the building blocks, ensuring your components are accessible will make your CLIs usable by a wider audience. + +## General Principles + +Provide screen reader-friendly output: Use the useIsScreenReaderEnabled hook to detect if a screen reader is active. You can then render a more descriptive output for screen reader users. +Leverage ARIA props: For components that have a specific role (e.g., a checkbox or a button), use the aria-role, aria-state, and aria-label props on and to provide semantic meaning to screen readers. diff --git a/packages/cli/.rdmind/settings.json b/packages/cli/.rdmind/settings.json new file mode 100644 index 00000000..b435f054 --- /dev/null +++ b/packages/cli/.rdmind/settings.json @@ -0,0 +1,6 @@ +{ + "extensions": { + "disabled": [] + }, + "$version": 2 +} diff --git a/packages/cli/src/commands/extensions/examples/context/RDMind.md b/packages/cli/src/commands/extensions/examples/context/RDMind.md new file mode 100644 index 00000000..22f6bbce --- /dev/null +++ b/packages/cli/src/commands/extensions/examples/context/RDMind.md @@ -0,0 +1,8 @@ +# Ink Library Screen Reader Guidance + +When building custom components, it's important to keep accessibility in mind. While Ink provides the building blocks, ensuring your components are accessible will make your CLIs usable by a wider audience. + +## General Principles + +Provide screen reader-friendly output: Use the useIsScreenReaderEnabled hook to detect if a screen reader is active. You can then render a more descriptive output for screen reader users. +Leverage ARIA props: For components that have a specific role (e.g., a checkbox or a button), use the aria-role, aria-state, and aria-label props on and to provide semantic meaning to screen readers. diff --git a/packages/core/src/core/tokenLimits.test.ts b/packages/core/src/core/tokenLimits.test.ts index bb9f0fd2..b2cbbd24 100644 --- a/packages/core/src/core/tokenLimits.test.ts +++ b/packages/core/src/core/tokenLimits.test.ts @@ -64,6 +64,12 @@ describe('normalize', () => { expect(normalize('qwen-vl-max-latest')).toBe('qwen-vl-max-latest'); }); + it('should preserve date suffixes for Kimi K2 models', () => { + expect(normalize('kimi-k2-0905-preview')).toBe('kimi-k2-0905'); + expect(normalize('kimi-k2-0711-preview')).toBe('kimi-k2-0711'); + expect(normalize('kimi-k2-turbo-preview')).toBe('kimi-k2-turbo'); + }); + it('should remove date like suffixes', () => { expect(normalize('deepseek-r1-0528')).toBe('deepseek-r1'); }); @@ -213,7 +219,7 @@ describe('tokenLimit', () => { }); }); - describe('Other models', () => { + describe('DeepSeek', () => { it('should return the correct limit for deepseek-r1', () => { expect(tokenLimit('deepseek-r1')).toBe(131072); }); @@ -226,9 +232,27 @@ describe('tokenLimit', () => { it('should return the correct limit for deepseek-v3.2', () => { expect(tokenLimit('deepseek-v3.2-exp')).toBe(131072); }); - it('should return the correct limit for kimi-k2-instruct', () => { - expect(tokenLimit('kimi-k2-instruct')).toBe(131072); + }); + + describe('Moonshot Kimi', () => { + it('should return the correct limit for kimi-k2-0905-preview', () => { + expect(tokenLimit('kimi-k2-0905-preview')).toBe(262144); // 256K + expect(tokenLimit('kimi-k2-0905')).toBe(262144); }); + it('should return the correct limit for kimi-k2-turbo-preview', () => { + expect(tokenLimit('kimi-k2-turbo-preview')).toBe(262144); // 256K + expect(tokenLimit('kimi-k2-turbo')).toBe(262144); + }); + it('should return the correct limit for kimi-k2-0711-preview', () => { + expect(tokenLimit('kimi-k2-0711-preview')).toBe(131072); // 128K + expect(tokenLimit('kimi-k2-0711')).toBe(131072); + }); + it('should return the correct limit for kimi-k2-instruct', () => { + expect(tokenLimit('kimi-k2-instruct')).toBe(131072); // 128K + }); + }); + + describe('Other models', () => { it('should return the correct limit for gpt-oss', () => { expect(tokenLimit('gpt-oss')).toBe(131072); }); diff --git a/packages/core/src/core/tokenLimits.ts b/packages/core/src/core/tokenLimits.ts index cd3a0a0f..f2693075 100644 --- a/packages/core/src/core/tokenLimits.ts +++ b/packages/core/src/core/tokenLimits.ts @@ -47,8 +47,13 @@ export function normalize(model: string): string { // remove trailing build / date / revision suffixes: // - dates (e.g., -20250219), -v1, version numbers, 'latest', 'preview' etc. s = s.replace(/-preview/g, ''); - // Special handling for Qwen model names that include "-latest" as part of the model name - if (!s.match(/^qwen-(?:plus|flash|vl-max)-latest$/)) { + // Special handling for model names that include date/version as part of the model identifier + // - Qwen models: qwen-plus-latest, qwen-flash-latest, qwen-vl-max-latest + // - Kimi models: kimi-k2-0905, kimi-k2-0711, etc. (keep date for version distinction) + if ( + !s.match(/^qwen-(?:plus|flash|vl-max)-latest$/) && + !s.match(/^kimi-k2-\d{4}$/) + ) { // Regex breakdown: // -(?:...)$ - Non-capturing group for suffixes at the end of the string // The following patterns are matched within the group: @@ -165,9 +170,16 @@ const PATTERNS: Array<[RegExp, TokenCount]> = [ [/^deepseek-v3(?:\.\d+)?(?:-.*)?$/, LIMITS['128k']], // ------------------- - // GPT-OSS / Kimi / Llama & Mistral examples + // Moonshot / Kimi + // ------------------- + [/^kimi-k2-0905$/, LIMITS['256k']], // Kimi-k2-0905-preview: 256K context + [/^kimi-k2-turbo.*$/, LIMITS['256k']], // Kimi-k2-turbo-preview: 256K context + [/^kimi-k2-0711$/, LIMITS['128k']], // Kimi-k2-0711-preview: 128K context + [/^kimi-k2-instruct.*$/, LIMITS['128k']], // Kimi-k2-instruct: 128K context + + // ------------------- + // GPT-OSS / Llama & Mistral examples // ------------------- - [/^kimi-k2-instruct.*$/, LIMITS['128k']], [/^gpt-oss.*$/, LIMITS['128k']], [/^llama-4-scout.*$/, LIMITS['10m']], [/^mistral-large-2.*$/, LIMITS['128k']],