Coverage for sources / agentsmgr / renderers / qwen.py: 30%
32 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-04 21:55 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-04 21:55 +0000
1# vim: set filetype=python fileencoding=utf-8:
2# -*- coding: utf-8 -*-
4#============================================================================#
5# #
6# Licensed under the Apache License, Version 2.0 (the "License"); #
7# you may not use this file except in compliance with the License. #
8# You may obtain a copy of the License at #
9# #
10# http://www.apache.org/licenses/LICENSE-2.0 #
11# #
12# Unless required by applicable law or agreed to in writing, software #
13# distributed under the License is distributed on an "AS IS" BASIS, #
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15# See the License for the specific language governing permissions and #
16# limitations under the License. #
17# #
18#============================================================================#
21''' Qwen Code renderer implementation.
23 Provides path resolution and targeting mode validation for Qwen Code,
24 which supports both per-user and per-project configuration.
25'''
28from . import __
29from . import base as _base
32class QwenRenderer( _base.RendererBase ):
33 ''' Renderer for Qwen Code coder.
35 Supports both per-user and per-project configuration modes.
36 Per-user mode defaults to ~/.qwen/ with configuration file
37 override support via directory field in coder config.
38 '''
40 name = 'qwen'
41 modes_available = frozenset( ( 'per-user', 'per-project' ) )
42 mode_default = 'per-project'
43 memory_filename = 'QWEN.md'
44 item_types_available = frozenset( ( 'commands', 'agents' ) )
46 def get_template_flavor( self, item_type: str ) -> str:
47 ''' Determines template flavor for Qwen Code.
49 Qwen shares markdown command format with Claude/Gemini
50 (via gemini.toml.jinja for TOML) but uses own agent format
51 with YAML frontmatter, so returns 'gemini' for commands
52 and 'qwen' for agents.
53 '''
54 if item_type == 'commands':
55 return 'gemini'
56 return 'qwen'
58 def resolve_base_directory(
59 self,
60 mode: _base.ExplicitTargetMode,
61 target: __.Path,
62 configuration: __.cabc.Mapping[ str, __.typx.Any ],
63 environment: __.cabc.Mapping[ str, str ],
64 ) -> __.Path:
65 ''' Resolves base output directory for Qwen Code.
67 Per-project: .auxiliary/configuration/coders/qwen/
68 Per-user: ~/.qwen/ with configuration file overrides.
69 '''
70 self.validate_mode( mode )
71 if mode == 'per-project':
72 return target / ".auxiliary/configuration/coders/qwen"
73 if mode == 'per-user':
74 return self._resolve_user_directory( configuration, environment )
75 raise __.TargetModeNoSupport( self.name, mode )
77 def _resolve_user_directory(
78 self,
79 configuration: __.cabc.Mapping[ str, __.typx.Any ],
80 environment: __.cabc.Mapping[ str, str ],
81 ) -> __.Path:
82 ''' Resolves per-user directory following precedence rules.
84 Precedence order:
85 1. Configuration file override (directory field for this coder)
86 2. Default ~/.qwen/ location
88 Note: Qwen does not provide environment variable override
89 for user config path (unlike Claude's CLAUDE_CONFIG_DIR).
90 '''
91 coder_configuration = self._extract_coder_configuration(
92 configuration )
93 if 'directory' in coder_configuration:
94 directory = __.Path( coder_configuration[ 'directory' ] )
95 return directory.expanduser( )
96 return __.Path.home( ) / '.qwen'
98 def _extract_coder_configuration(
99 self, configuration: __.cabc.Mapping[ str, __.typx.Any ]
100 ) -> __.cabc.Mapping[ str, __.typx.Any ]:
101 ''' Extracts configuration for this specific coder.
103 Looks for coder entry in configuration coders array by name.
104 '''
105 coders = configuration.get( 'coders', ( ) )
106 for coder in coders:
107 if coder.get( 'name' ) == self.name:
108 return coder
109 return { }
112_base.RENDERERS[ 'qwen' ] = QwenRenderer( )