mirror of
https://github.com/stablyai/orca.git
synced 2026-09-25 16:02:38 +00:00
* fix(native-chat): pass agent-implemented slash commands through to the agent Claim what the host implements; pass through what the agent implements. Claude's harness expands a slash command out of the message text, so the host claimed catalog commands it had no way to run and answered "/init is not available in chat sessions" for commands Claude does run. Codex's app-server has no slash parser at all, so its catalog stays claimed — except /goal, which the model carries out through its own goal tools. * fix(native-chat): offer the agent-run commands in the structured picker Codex reports no command catalog, so its structured `/` menu is the host fallback -- which listed only the host's own commands and hid `/goal`, the one command the model itself acts on. The picker now appends the profile's text-driven commands, described from the curated catalog, so a command that passes through is discoverable and not merely typable. The menu invariant holds either way: a pick is answered by the host or run by the agent, never refused with "not available in chat sessions". * fix mobile structured command reconciliation * fix(mobile): keep native chat controller within lint budget * fix mobile controller lint budget --------- Co-authored-by: Merge Sim <sim@local>
59 lines
2.1 KiB
TypeScript
59 lines
2.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
getHostClaimedNativeChatCommands,
|
|
getNativeChatAgentProfile,
|
|
getVerifiedNativeChatCommands
|
|
} from './native-chat-agent-profiles'
|
|
|
|
describe('native chat agent picker profiles', () => {
|
|
// The composer types the same `/` for every agent; skillPrefix is only the
|
|
// form a picked skill is written as.
|
|
it('keeps Codex skills invocable as dollar tokens', () => {
|
|
expect(getNativeChatAgentProfile('codex')).toMatchObject({
|
|
skillPrefix: '$',
|
|
skillSourceOwner: 'codex'
|
|
})
|
|
})
|
|
|
|
it('writes Claude-family and Grok skills as slash tokens', () => {
|
|
expect(getNativeChatAgentProfile('claude')).toMatchObject({
|
|
skillPrefix: '/',
|
|
skillSourceOwner: 'claude'
|
|
})
|
|
expect(getNativeChatAgentProfile('openclaude')).toMatchObject({ skillSourceOwner: 'claude' })
|
|
expect(getNativeChatAgentProfile('grok')).toMatchObject({
|
|
skillPrefix: '/',
|
|
skillSourceOwner: 'grok'
|
|
})
|
|
})
|
|
|
|
it('does not grant custom or unverified agents a skill grammar', () => {
|
|
expect(getNativeChatAgentProfile('custom-agent')).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('host-claimed native chat commands', () => {
|
|
function names(agent: string): string[] {
|
|
return getHostClaimedNativeChatCommands(agent).map((command) => command.name)
|
|
}
|
|
|
|
// Claude's harness expands a slash command out of the message body, so claiming
|
|
// its catalog only answered "/init is not available" for commands that do run.
|
|
it('claims nothing from the Claude-family catalog', () => {
|
|
expect(names('claude')).toEqual([])
|
|
expect(names('openclaude')).toEqual([])
|
|
})
|
|
|
|
it('keeps the Codex catalog claimed except the model-driven /goal', () => {
|
|
expect(names('codex')).toContain('permissions')
|
|
expect(names('codex')).toContain('vim')
|
|
expect(names('codex')).not.toContain('goal')
|
|
expect(getVerifiedNativeChatCommands('codex').map((command) => command.name)).toContain('goal')
|
|
})
|
|
|
|
it('claims the whole catalog for agents with no pass-through policy', () => {
|
|
expect(names('custom-agent')).toEqual(['clear', 'help'])
|
|
expect(names('grok')).toEqual([])
|
|
})
|
|
})
|