pilot.linkstec 0.0.16__tar.gz → 0.0.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pilot.linkstec might be problematic. Click here for more details.

Files changed (39) hide show
  1. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/PKG-INFO +1 -1
  2. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/pyproject.toml +1 -1
  3. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/config/config_reader.py +0 -2
  4. pilot_linkstec-0.0.18/src/pilot/generater/vertexai.py +158 -0
  5. pilot_linkstec-0.0.18/src/pilot/processor/code_processor.py +8 -0
  6. pilot_linkstec-0.0.18/src/pilot/processor/code_processor_pipeline.py +14 -0
  7. pilot_linkstec-0.0.18/src/pilot/util/__init__.py +0 -0
  8. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot.linkstec.egg-info/PKG-INFO +1 -1
  9. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot.linkstec.egg-info/SOURCES.txt +3 -0
  10. pilot_linkstec-0.0.16/src/pilot/generater/vertexai.py +0 -72
  11. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/LICENSE +0 -0
  12. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/README.md +0 -0
  13. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/setup.cfg +0 -0
  14. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/__init__.py +0 -0
  15. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/config/__init__.py +0 -0
  16. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/control/__init__.py +0 -0
  17. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/control/control_interface.py +0 -0
  18. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/control/impl/__init__.py +0 -0
  19. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/control/impl/base_controller.py +0 -0
  20. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/conver/__init__.py +0 -0
  21. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/conver/converfileEncodding.py +0 -0
  22. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/conver/nkf_converter.py +0 -0
  23. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/generater/__init__.py +0 -0
  24. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/job/__init__.py +0 -0
  25. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/job/impl/__init__.py +0 -0
  26. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/job/impl/base_job.py +0 -0
  27. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/job/job_interface.py +0 -0
  28. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/logging/__init__.py +0 -0
  29. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/logging/logger.py +0 -0
  30. {pilot_linkstec-0.0.16/src/pilot/splitters → pilot_linkstec-0.0.18/src/pilot/processor}/__init__.py +0 -0
  31. {pilot_linkstec-0.0.16/src/pilot/unit → pilot_linkstec-0.0.18/src/pilot/splitters}/__init__.py +0 -0
  32. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/splitters/cobolsplitter.py +0 -0
  33. {pilot_linkstec-0.0.16/src/pilot/unit/impl → pilot_linkstec-0.0.18/src/pilot/unit}/__init__.py +0 -0
  34. {pilot_linkstec-0.0.16/src/pilot/util → pilot_linkstec-0.0.18/src/pilot/unit/impl}/__init__.py +0 -0
  35. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/unit/impl/base_unit.py +0 -0
  36. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/unit/unit_interface.py +0 -0
  37. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot/util/files.py +0 -0
  38. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot.linkstec.egg-info/dependency_links.txt +0 -0
  39. {pilot_linkstec-0.0.16 → pilot_linkstec-0.0.18}/src/pilot.linkstec.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pilot.linkstec
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary: pilot of the ship, a tool for managing and deploying Python projects.
5
5
  Author-email: wanglr <wanglr1980@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pilot.linkstec"
3
- version = "0.0.16"
3
+ version = "0.0.18"
4
4
  authors = [
5
5
  { name="wanglr", email="wanglr1980@gmail.com" },
6
6
  ]
@@ -14,8 +14,6 @@ class ConfigDTO:
14
14
  runsteps: list[str]
15
15
  multisteps: list[str]
16
16
 
17
-
18
-
19
17
  class ConfigReader:
20
18
  def __init__(self, filename = None):
21
19
  filepath = None
@@ -0,0 +1,158 @@
1
+ import re
2
+ import threading
3
+ from typing import Dict, Any, Optional
4
+
5
+ import tiktoken
6
+ from vertexai.generative_models import GenerativeModel, ChatSession
7
+ import os
8
+
9
+ class VertexAISingleton:
10
+ _instance: Optional['VertexAISingleton'] = None
11
+ _lock = threading.Lock()
12
+ _tokenizer_cache = {}
13
+ encoding = None
14
+
15
+ SQL_SYSTEM_PROMPT_EN = (
16
+ "If there is any SQL-related processing \n"
17
+ "1. If there is an SQL statement like \"SELECT COUNT(X) INTO :COLUMN FROM TABLE_NAME;\" please recognize TABLE_NAME as a table."
18
+ )
19
+
20
+
21
+ def __new__(cls, model_name: str = "gemini-2.5-pro", system_prompt: Optional[str] = None):
22
+ if cls._instance is None:
23
+ with cls._lock:
24
+ if cls._instance is None:
25
+ cls._instance = super(VertexAISingleton, cls).__new__(cls)
26
+ cls._instance._initialized = False
27
+ return cls._instance
28
+
29
+ def __init__(self, model_name: str = "gemini-2.5-pro", system_prompt: Optional[str] = None):
30
+ if not self._initialized:
31
+ with self._lock:
32
+ if not self._initialized:
33
+ self.model = GenerativeModel(model_name)
34
+ self.encoding = tiktoken.get_encoding("cl100k_base")
35
+ # system_promptにSQL_SYSTEM_PROMPT_ENを追加
36
+ if system_prompt:
37
+ self.system_prompt = f"{system_prompt.rstrip()}\n\n{self.SQL_SYSTEM_PROMPT_EN}"
38
+ else:
39
+ self.system_prompt = self.SQL_SYSTEM_PROMPT_EN
40
+ self._initialized = True
41
+ else:
42
+ # 既存インスタンスでもsystem_promptを更新可能に
43
+ if system_prompt is not None:
44
+ self.system_prompt = f"{system_prompt.rstrip()}\n\n{self.SQL_SYSTEM_PROMPT_EN}" if system_prompt else self.SQL_SYSTEM_PROMPT_EN
45
+
46
+ def generate_content(self, prompt: str) -> Dict[str, Any]:
47
+ """複数スレッドから安全に呼び出し可能"""
48
+ try:
49
+ # system_promptがあれば先頭に付与
50
+ full_prompt = f"{self.system_prompt}\n{prompt}" if getattr(self, "system_prompt", None) else prompt
51
+ response = self.model.generate_content(self.exchange_prompt(full_prompt))
52
+ return {
53
+ "prompt": prompt,
54
+ "response": self._remove_code_fence(response.text),
55
+ "success": True,
56
+ "error": None
57
+ }
58
+ except Exception as e:
59
+ return {
60
+ "prompt": prompt,
61
+ "response": None,
62
+ "success": False,
63
+ "error": str(e)
64
+ }
65
+
66
+ def start_chat(self) -> ChatSession:
67
+ """新しいチャットセッションを開始"""
68
+ return self.model.start_chat()
69
+
70
+ def count_tokens(self, text: str) -> int:
71
+ """与えられたテキストのトークン数を返す(bert-base-uncasedのみ使用)"""
72
+ try:
73
+ tokens = self.encoding.encode(text)
74
+ return len(tokens)
75
+ except Exception as e:
76
+ print(f"トークン計算失敗: {e}")
77
+ return 0
78
+
79
+ def _remove_code_fence(self, text: str) -> str:
80
+ lines = text.splitlines()
81
+ if lines and lines[0].startswith("```"):
82
+ lines = lines[1:]
83
+ if lines and lines[-1].startswith("```"):
84
+ lines = lines[:-1]
85
+ return "\n".join(lines)
86
+
87
+
88
+ def exchange_prompt(self, prompt: str) -> str:
89
+ # EXEC SQL ... END-EXEC. のSQL部分を抽出してフラット化
90
+ rtn_prompt = ""
91
+ rtn_prompt = self.fix_initialize(rtn_prompt)
92
+ rtn_prompt = self.extract_and_flatten_sql(rtn_prompt)
93
+ return rtn_prompt
94
+
95
+ def fix_initialize(self, text: str) -> str:
96
+ # SECTION ... EXIT. ブロック内のINITIALIZE文を処理
97
+ def process_section_block(match):
98
+ section_content = match.group(0)
99
+
100
+ # INITIALIZE の行を結合する(SECTION-EXIT間のみ)
101
+ # INITIALIZEで始まる行の次の行が空白+文字列の場合に結合
102
+ pattern_init = r'^(\s*INITIALIZE\s+[^\n]*)\n(\s+[^\n]+(?:\s+[^\n]+)*)'
103
+
104
+ def repl_init(m):
105
+ init_line = m.group(1).rstrip()
106
+ next_lines = m.group(2).strip()
107
+ return f'{init_line} {next_lines}'
108
+
109
+ section_content = re.sub(pattern_init, repl_init, section_content, flags=re.MULTILINE)
110
+
111
+ # ブロック内 COUNT(*) → COUNT(1) へ置換する
112
+ section_content = re.sub(r'COUNT\(\s*\*\s*\)', 'COUNT(1)', section_content, flags=re.IGNORECASE)
113
+
114
+ return section_content
115
+
116
+ # SECTION から EXIT. までのブロックを検索して処理
117
+ section_pattern = r'(\w+\s+SECTION\s*\..*?EXIT\s*\.)'
118
+ text = re.sub(section_pattern, process_section_block, text, flags=re.DOTALL | re.IGNORECASE)
119
+
120
+ return text
121
+
122
+ def replace_aaa_in_section(code: str) -> str:
123
+ """
124
+ SECTION.~EXIT.ブロック中のAAAをBBBに置換し、全体をstrで返す
125
+ """
126
+ pattern = r"SECTION.(.*?)(EXIT.)"
127
+
128
+ def repl(m):
129
+ block = m.group(1)
130
+ block_modified = block.replace("AAA", "BBB")
131
+ return f"SECTION.{block_modified}EXIT."
132
+
133
+ result = re.sub(pattern, repl, code, flags=re.DOTALL | re.IGNORECASE)
134
+ return result
135
+
136
+ def extract_and_flatten_sql(self, code):
137
+ # EXEC SQL ... END-EXEC. にマッチ
138
+ pattern = r"EXEC SQL(.*?)END-EXEC\.?"
139
+
140
+ def repl(m):
141
+ # .*?でSQL部分取得
142
+ raw_sql = m.group(1)
143
+ # コメント(*以降)除去(複数行まとめてOK)
144
+ no_comment = re.sub(r"\*.*", "", raw_sql)
145
+ # 改行/連続スペースを単一スペースに
146
+ flattened = re.sub(r"\s+", " ", no_comment).strip()
147
+ # 置換内容
148
+ return f"EXEC SQL {flattened} END-EXEC."
149
+
150
+ # 全て置換
151
+ result = re.sub(pattern, repl, code, flags=re.DOTALL | re.IGNORECASE)
152
+ return result
153
+
154
+
155
+ @classmethod
156
+ def get_instance(cls, model_name: str = "gemini-2.5-pro", system_prompt: Optional[str] = None) -> 'VertexAISingleton':
157
+ """インスタンスを取得"""
158
+ return cls(model_name, system_prompt)
@@ -0,0 +1,8 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import List
3
+
4
+
5
+ class CodeProcessor(ABC):
6
+ @abstractmethod
7
+ def process(self, lines: List[str]) -> List[str]:
8
+ pass
@@ -0,0 +1,14 @@
1
+ from typing import List
2
+
3
+ from pilot.processor.code_processor import CodeProcessor
4
+
5
+
6
+ class CodeProcessorPipeline:
7
+ def __init__(self, processors: List[CodeProcessor]):
8
+ self.processors = processors
9
+
10
+ def run(self, lines: List[str]) -> List[str]:
11
+ result = lines
12
+ for processor in self.processors:
13
+ result = processor.process(result)
14
+ return result
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pilot.linkstec
3
- Version: 0.0.16
3
+ Version: 0.0.18
4
4
  Summary: pilot of the ship, a tool for managing and deploying Python projects.
5
5
  Author-email: wanglr <wanglr1980@gmail.com>
6
6
  License-Expression: MIT
@@ -23,6 +23,9 @@ src/pilot/job/impl/__init__.py
23
23
  src/pilot/job/impl/base_job.py
24
24
  src/pilot/logging/__init__.py
25
25
  src/pilot/logging/logger.py
26
+ src/pilot/processor/__init__.py
27
+ src/pilot/processor/code_processor.py
28
+ src/pilot/processor/code_processor_pipeline.py
26
29
  src/pilot/splitters/__init__.py
27
30
  src/pilot/splitters/cobolsplitter.py
28
31
  src/pilot/unit/__init__.py
@@ -1,72 +0,0 @@
1
- import threading
2
- from typing import Dict, Any, Optional
3
-
4
- import tiktoken
5
- from vertexai.generative_models import GenerativeModel, ChatSession
6
- import os
7
-
8
- class VertexAISingleton:
9
- _instance: Optional['VertexAISingleton'] = None
10
- _lock = threading.Lock()
11
- _tokenizer_cache = {}
12
- encoding = None
13
-
14
- def __new__(cls, model_name: str = "gemini-2.5-pro"):
15
- if cls._instance is None:
16
- with cls._lock:
17
- if cls._instance is None:
18
- cls._instance = super(VertexAISingleton, cls).__new__(cls)
19
- cls._instance._initialized = False
20
- return cls._instance
21
-
22
- def __init__(self, model_name: str = "gemini-2.5-pro"):
23
- if not self._initialized:
24
- with self._lock:
25
- if not self._initialized:
26
- self.model = GenerativeModel(model_name)
27
- self.encoding = tiktoken.get_encoding("cl100k_base")
28
- self._initialized = True
29
-
30
- def generate_content(self, prompt: str) -> Dict[str, Any]:
31
- """複数スレッドから安全に呼び出し可能"""
32
- try:
33
- response = self.model.generate_content(prompt)
34
- return {
35
- "prompt": prompt,
36
- "response": self._remove_code_fence(response.text),
37
- "success": True,
38
- "error": None
39
- }
40
- except Exception as e:
41
- return {
42
- "prompt": prompt,
43
- "response": None,
44
- "success": False,
45
- "error": str(e)
46
- }
47
-
48
- def start_chat(self) -> ChatSession:
49
- """新しいチャットセッションを開始"""
50
- return self.model.start_chat()
51
-
52
- def count_tokens(self, text: str) -> int:
53
- """与えられたテキストのトークン数を返す(bert-base-uncasedのみ使用)"""
54
- try:
55
- tokens = self.encoding.encode(text)
56
- return len(tokens)
57
- except Exception as e:
58
- print(f"トークン計算失敗: {e}")
59
- return 0
60
-
61
- def _remove_code_fence(self, text: str) -> str:
62
- lines = text.splitlines()
63
- if lines and lines[0].startswith("```"):
64
- lines = lines[1:]
65
- if lines and lines[-1].startswith("```"):
66
- lines = lines[:-1]
67
- return "\n".join(lines)
68
-
69
- @classmethod
70
- def get_instance(cls, model_name: str = "gemini-2.5-pro") -> 'VertexAISingleton':
71
- """インスタンスを取得"""
72
- return cls(model_name)
File without changes