@intrect/openswarm 0.2.2 → 0.4.0

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.
Files changed (176) hide show
  1. package/README.md +236 -331
  2. package/config.example.yaml +36 -13
  3. package/dist/adapters/agenticLoop.d.ts +90 -0
  4. package/dist/adapters/agenticLoop.d.ts.map +1 -0
  5. package/dist/adapters/agenticLoop.js +141 -0
  6. package/dist/adapters/agenticLoop.js.map +1 -0
  7. package/dist/adapters/base.d.ts.map +1 -1
  8. package/dist/adapters/base.js +4 -0
  9. package/dist/adapters/base.js.map +1 -1
  10. package/dist/adapters/cryptoQuantAdapter.js +1 -1
  11. package/dist/adapters/cryptoQuantAdapter.js.map +1 -1
  12. package/dist/adapters/gpt.d.ts +19 -0
  13. package/dist/adapters/gpt.d.ts.map +1 -0
  14. package/dist/adapters/gpt.js +251 -0
  15. package/dist/adapters/gpt.js.map +1 -0
  16. package/dist/adapters/index.d.ts +2 -0
  17. package/dist/adapters/index.d.ts.map +1 -1
  18. package/dist/adapters/index.js +6 -0
  19. package/dist/adapters/index.js.map +1 -1
  20. package/dist/adapters/local.d.ts +31 -0
  21. package/dist/adapters/local.d.ts.map +1 -0
  22. package/dist/adapters/local.js +320 -0
  23. package/dist/adapters/local.js.map +1 -0
  24. package/dist/adapters/tools.d.ts +30 -0
  25. package/dist/adapters/tools.d.ts.map +1 -0
  26. package/dist/adapters/tools.js +219 -0
  27. package/dist/adapters/tools.js.map +1 -0
  28. package/dist/adapters/types.d.ts +6 -1
  29. package/dist/adapters/types.d.ts.map +1 -1
  30. package/dist/agents/pairPipeline.d.ts +7 -0
  31. package/dist/agents/pairPipeline.d.ts.map +1 -1
  32. package/dist/agents/pairPipeline.js +99 -7
  33. package/dist/agents/pairPipeline.js.map +1 -1
  34. package/dist/agents/pipelineGuards.d.ts.map +1 -1
  35. package/dist/agents/pipelineGuards.js +84 -2
  36. package/dist/agents/pipelineGuards.js.map +1 -1
  37. package/dist/agents/worker.d.ts +3 -0
  38. package/dist/agents/worker.d.ts.map +1 -1
  39. package/dist/agents/worker.js +1 -0
  40. package/dist/agents/worker.js.map +1 -1
  41. package/dist/auth/index.d.ts +3 -0
  42. package/dist/auth/index.d.ts.map +1 -0
  43. package/dist/auth/index.js +6 -0
  44. package/dist/auth/index.js.map +1 -0
  45. package/dist/auth/oauthPkce.d.ts +21 -0
  46. package/dist/auth/oauthPkce.d.ts.map +1 -0
  47. package/dist/auth/oauthPkce.js +212 -0
  48. package/dist/auth/oauthPkce.js.map +1 -0
  49. package/dist/auth/oauthStore.d.ts +24 -0
  50. package/dist/auth/oauthStore.d.ts.map +1 -0
  51. package/dist/auth/oauthStore.js +96 -0
  52. package/dist/auth/oauthStore.js.map +1 -0
  53. package/dist/automation/autonomousRunner.d.ts +5 -5
  54. package/dist/automation/runnerTypes.d.ts +1 -1
  55. package/dist/automation/runnerTypes.d.ts.map +1 -1
  56. package/dist/cli/authHandler.d.ts +16 -0
  57. package/dist/cli/authHandler.d.ts.map +1 -0
  58. package/dist/cli/authHandler.js +93 -0
  59. package/dist/cli/authHandler.js.map +1 -0
  60. package/dist/cli/checkHandler.d.ts +25 -0
  61. package/dist/cli/checkHandler.d.ts.map +1 -0
  62. package/dist/cli/checkHandler.js +465 -0
  63. package/dist/cli/checkHandler.js.map +1 -0
  64. package/dist/cli.js +64 -0
  65. package/dist/cli.js.map +1 -1
  66. package/dist/core/config.d.ts +17 -4
  67. package/dist/core/config.d.ts.map +1 -1
  68. package/dist/core/config.js +21 -8
  69. package/dist/core/config.js.map +1 -1
  70. package/dist/core/service.d.ts.map +1 -1
  71. package/dist/core/service.js +18 -8
  72. package/dist/core/service.js.map +1 -1
  73. package/dist/core/types.d.ts +4 -2
  74. package/dist/core/types.d.ts.map +1 -1
  75. package/dist/issues/graphql/resolvers.d.ts +252 -0
  76. package/dist/issues/graphql/resolvers.d.ts.map +1 -0
  77. package/dist/issues/graphql/resolvers.js +88 -0
  78. package/dist/issues/graphql/resolvers.js.map +1 -0
  79. package/dist/issues/graphql/server.d.ts +13 -0
  80. package/dist/issues/graphql/server.d.ts.map +1 -0
  81. package/dist/issues/graphql/server.js +56 -0
  82. package/dist/issues/graphql/server.js.map +1 -0
  83. package/dist/issues/graphql/typeDefs.d.ts +2 -0
  84. package/dist/issues/graphql/typeDefs.d.ts.map +1 -0
  85. package/dist/issues/graphql/typeDefs.js +251 -0
  86. package/dist/issues/graphql/typeDefs.js.map +1 -0
  87. package/dist/issues/index.d.ts +8 -0
  88. package/dist/issues/index.d.ts.map +1 -0
  89. package/dist/issues/index.js +11 -0
  90. package/dist/issues/index.js.map +1 -0
  91. package/dist/issues/issueBoardHtml.d.ts +2 -0
  92. package/dist/issues/issueBoardHtml.d.ts.map +1 -0
  93. package/dist/issues/issueBoardHtml.js +677 -0
  94. package/dist/issues/issueBoardHtml.js.map +1 -0
  95. package/dist/issues/linearBridge.d.ts +27 -0
  96. package/dist/issues/linearBridge.d.ts.map +1 -0
  97. package/dist/issues/linearBridge.js +211 -0
  98. package/dist/issues/linearBridge.js.map +1 -0
  99. package/dist/issues/memoryBridge.d.ts +35 -0
  100. package/dist/issues/memoryBridge.d.ts.map +1 -0
  101. package/dist/issues/memoryBridge.js +184 -0
  102. package/dist/issues/memoryBridge.js.map +1 -0
  103. package/dist/issues/schema.d.ts +162 -0
  104. package/dist/issues/schema.d.ts.map +1 -0
  105. package/dist/issues/schema.js +121 -0
  106. package/dist/issues/schema.js.map +1 -0
  107. package/dist/issues/sqliteStore.d.ts +90 -0
  108. package/dist/issues/sqliteStore.d.ts.map +1 -0
  109. package/dist/issues/sqliteStore.js +488 -0
  110. package/dist/issues/sqliteStore.js.map +1 -0
  111. package/dist/knowledge/index.d.ts.map +1 -1
  112. package/dist/knowledge/index.js +9 -3
  113. package/dist/knowledge/index.js.map +1 -1
  114. package/dist/linear/linear.d.ts +4 -0
  115. package/dist/linear/linear.d.ts.map +1 -1
  116. package/dist/linear/linear.js +27 -0
  117. package/dist/linear/linear.js.map +1 -1
  118. package/dist/locale/prompts/en.d.ts.map +1 -1
  119. package/dist/locale/prompts/en.js +32 -2
  120. package/dist/locale/prompts/en.js.map +1 -1
  121. package/dist/locale/prompts/ko.d.ts.map +1 -1
  122. package/dist/locale/prompts/ko.js +32 -2
  123. package/dist/locale/prompts/ko.js.map +1 -1
  124. package/dist/locale/types.d.ts +17 -0
  125. package/dist/locale/types.d.ts.map +1 -1
  126. package/dist/registry/bsDetector.d.ts +24 -0
  127. package/dist/registry/bsDetector.d.ts.map +1 -0
  128. package/dist/registry/bsDetector.js +276 -0
  129. package/dist/registry/bsDetector.js.map +1 -0
  130. package/dist/registry/entityScanner.d.ts +36 -0
  131. package/dist/registry/entityScanner.d.ts.map +1 -0
  132. package/dist/registry/entityScanner.js +693 -0
  133. package/dist/registry/entityScanner.js.map +1 -0
  134. package/dist/registry/graphql/resolvers.d.ts +778 -0
  135. package/dist/registry/graphql/resolvers.d.ts.map +1 -0
  136. package/dist/registry/graphql/resolvers.js +127 -0
  137. package/dist/registry/graphql/resolvers.js.map +1 -0
  138. package/dist/registry/graphql/typeDefs.d.ts +2 -0
  139. package/dist/registry/graphql/typeDefs.d.ts.map +1 -0
  140. package/dist/registry/graphql/typeDefs.js +276 -0
  141. package/dist/registry/graphql/typeDefs.js.map +1 -0
  142. package/dist/registry/index.d.ts +12 -0
  143. package/dist/registry/index.d.ts.map +1 -0
  144. package/dist/registry/index.js +18 -0
  145. package/dist/registry/index.js.map +1 -0
  146. package/dist/registry/issueBridge.d.ts +8 -0
  147. package/dist/registry/issueBridge.d.ts.map +1 -0
  148. package/dist/registry/issueBridge.js +30 -0
  149. package/dist/registry/issueBridge.js.map +1 -0
  150. package/dist/registry/memoryBridge.d.ts +13 -0
  151. package/dist/registry/memoryBridge.d.ts.map +1 -0
  152. package/dist/registry/memoryBridge.js +60 -0
  153. package/dist/registry/memoryBridge.js.map +1 -0
  154. package/dist/registry/schema.d.ts +307 -0
  155. package/dist/registry/schema.d.ts.map +1 -0
  156. package/dist/registry/schema.js +139 -0
  157. package/dist/registry/schema.js.map +1 -0
  158. package/dist/registry/sqliteStore.d.ts +101 -0
  159. package/dist/registry/sqliteStore.d.ts.map +1 -0
  160. package/dist/registry/sqliteStore.js +688 -0
  161. package/dist/registry/sqliteStore.js.map +1 -0
  162. package/dist/support/chatBackend.d.ts.map +1 -1
  163. package/dist/support/chatBackend.js +35 -4
  164. package/dist/support/chatBackend.js.map +1 -1
  165. package/dist/support/chatTui.d.ts.map +1 -1
  166. package/dist/support/chatTui.js +109 -3
  167. package/dist/support/chatTui.js.map +1 -1
  168. package/dist/support/dashboardHtml.d.ts +1 -1
  169. package/dist/support/dashboardHtml.d.ts.map +1 -1
  170. package/dist/support/dashboardHtml.js +1 -0
  171. package/dist/support/dashboardHtml.js.map +1 -1
  172. package/dist/support/web.d.ts.map +1 -1
  173. package/dist/support/web.js +16 -3
  174. package/dist/support/web.js.map +1 -1
  175. package/package.json +8 -2
  176. package/templates/TOOLS.md +2 -2
@@ -0,0 +1,251 @@
1
+ // ============================================
2
+ // OpenSwarm - GPT CLI Adapter
3
+ // Calls OpenAI Chat Completions API via OAuth token
4
+ // Agentic tool loop 지원 (read/write/edit/search/bash)
5
+ // ============================================
6
+ import { AuthProfileStore, ensureValidToken } from '../auth/index.js';
7
+ import { t } from '../locale/index.js';
8
+ import { runAgenticLoop, loopResultToCliResult } from './agenticLoop.js';
9
+ const OPENAI_API_BASE = 'https://api.openai.com/v1';
10
+ const DEFAULT_MODEL = 'gpt-4o';
11
+ const PROFILE_KEY = 'openai-gpt:default';
12
+ export class GptCliAdapter {
13
+ name = 'gpt';
14
+ capabilities = {
15
+ supportsStreaming: false,
16
+ supportsJsonOutput: true,
17
+ supportsModelSelection: true,
18
+ managedGit: false,
19
+ supportedSkills: [],
20
+ };
21
+ async isAvailable() {
22
+ try {
23
+ const store = new AuthProfileStore();
24
+ const profile = store.getProfile(PROFILE_KEY);
25
+ return profile !== null;
26
+ }
27
+ catch {
28
+ return false;
29
+ }
30
+ }
31
+ buildCommand(_options) {
32
+ // GPT 어댑터는 run()을 사용하므로 이 메서드는 호출되지 않음
33
+ return { command: 'echo', args: ['"GPT adapter uses run() — not shell spawn"'] };
34
+ }
35
+ async run(options) {
36
+ const store = new AuthProfileStore();
37
+ const startTime = Date.now();
38
+ // 1. 유효한 토큰 획득
39
+ let accessToken;
40
+ try {
41
+ accessToken = await ensureValidToken(store, PROFILE_KEY);
42
+ }
43
+ catch (err) {
44
+ return {
45
+ exitCode: 1,
46
+ stdout: '',
47
+ stderr: `Auth error: ${err instanceof Error ? err.message : String(err)}`,
48
+ durationMs: Date.now() - startTime,
49
+ };
50
+ }
51
+ const model = options.model ?? DEFAULT_MODEL;
52
+ // 2. 에이전틱 루프로 실행 (도구 사용 가능)
53
+ const callApi = this.createApiCaller(accessToken, store, model);
54
+ const loopOptions = {
55
+ prompt: options.prompt,
56
+ cwd: options.cwd ?? process.cwd(),
57
+ model,
58
+ callApi,
59
+ maxTurns: options.maxTurns ?? 15,
60
+ timeoutMs: options.timeoutMs || 300000,
61
+ onLog: options.onLog,
62
+ enableTools: true,
63
+ };
64
+ try {
65
+ const result = await runAgenticLoop(loopOptions);
66
+ if (options.onLog) {
67
+ options.onLog(`[GPT] ${result.apiCallCount} API calls, ${result.toolCallCount} tool uses, ${result.totalTokens} tokens`);
68
+ }
69
+ return loopResultToCliResult(result);
70
+ }
71
+ catch (err) {
72
+ return {
73
+ exitCode: 1,
74
+ stdout: '',
75
+ stderr: `GPT agentic loop failed: ${err instanceof Error ? err.message : String(err)}`,
76
+ durationMs: Date.now() - startTime,
77
+ };
78
+ }
79
+ }
80
+ /**
81
+ * OpenAI API 호출 함수 생성 (에이전틱 루프에 주입)
82
+ * 401 시 토큰 갱신 + 1회 재시도 포함
83
+ */
84
+ createApiCaller(initialToken, store, model) {
85
+ let token = initialToken;
86
+ let retried = false;
87
+ return async (messages, tools) => {
88
+ const body = {
89
+ model,
90
+ messages,
91
+ temperature: 0.2,
92
+ max_tokens: 16384,
93
+ };
94
+ if (tools.length > 0) {
95
+ body.tools = tools;
96
+ }
97
+ const doCall = async (accessToken) => {
98
+ const res = await fetch(`${OPENAI_API_BASE}/chat/completions`, {
99
+ method: 'POST',
100
+ headers: {
101
+ 'Authorization': `Bearer ${accessToken}`,
102
+ 'Content-Type': 'application/json',
103
+ },
104
+ body: JSON.stringify(body),
105
+ });
106
+ if (!res.ok) {
107
+ const errText = await res.text().catch(() => '');
108
+ // 401 → 토큰 갱신 후 1회 재시도
109
+ if (res.status === 401 && !retried) {
110
+ retried = true;
111
+ token = await refreshAndRetry(store);
112
+ return doCall(token);
113
+ }
114
+ throw new Error(`OpenAI API error (${res.status}): ${errText.slice(0, 500)}`);
115
+ }
116
+ return (await res.json());
117
+ };
118
+ return doCall(token);
119
+ };
120
+ }
121
+ parseWorkerOutput(raw) {
122
+ const text = raw.stdout;
123
+ return extractWorkerResultJson(text) ?? extractWorkerFromText(text);
124
+ }
125
+ parseReviewerOutput(raw) {
126
+ const text = raw.stdout;
127
+ return extractReviewerResultJson(text) ?? extractReviewerFromText(text);
128
+ }
129
+ }
130
+ async function refreshAndRetry(store) {
131
+ const profile = store.getProfile(PROFILE_KEY);
132
+ if (!profile) {
133
+ throw new Error('No auth profile found');
134
+ }
135
+ // 강제 갱신 (expires를 0으로 설정)
136
+ profile.expires = 0;
137
+ store.setProfile(PROFILE_KEY, profile);
138
+ return ensureValidToken(store, PROFILE_KEY);
139
+ }
140
+ // Worker/Reviewer output parsing (Codex 어댑터와 동일한 로직)
141
+ function extractWorkerResultJson(text) {
142
+ const jsonMatch = text.match(/```json\s*([\s\S]*?)\s*```/);
143
+ const jsonStr = jsonMatch?.[1] ?? findJsonObject(text, '"success"');
144
+ if (!jsonStr)
145
+ return null;
146
+ try {
147
+ const parsed = JSON.parse(jsonStr);
148
+ return {
149
+ success: Boolean(parsed.success),
150
+ summary: parsed.summary || t('common.fallback.noSummary'),
151
+ filesChanged: Array.isArray(parsed.filesChanged) ? parsed.filesChanged : [],
152
+ commands: Array.isArray(parsed.commands) ? parsed.commands : [],
153
+ output: text,
154
+ error: parsed.error,
155
+ confidencePercent: typeof parsed.confidencePercent === 'number'
156
+ ? parsed.confidencePercent : undefined,
157
+ haltReason: parsed.haltReason || undefined,
158
+ };
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ }
164
+ function extractWorkerFromText(text) {
165
+ const hasError = /error|fail|exception|cannot/i.test(text);
166
+ const hasSuccess = /success|completed|done|finished/i.test(text);
167
+ return {
168
+ success: !hasError || hasSuccess,
169
+ summary: extractSummary(text),
170
+ filesChanged: [],
171
+ commands: [],
172
+ output: text,
173
+ error: hasError ? extractErrorMessage(text) : undefined,
174
+ };
175
+ }
176
+ function extractReviewerResultJson(text) {
177
+ const jsonMatch = text.match(/```json\s*([\s\S]*?)\s*```/);
178
+ const jsonStr = jsonMatch?.[1] ?? findJsonObject(text, '"decision"');
179
+ if (!jsonStr)
180
+ return null;
181
+ try {
182
+ const parsed = JSON.parse(jsonStr);
183
+ const decision = parsed.decision === 'approve' || parsed.decision === 'reject'
184
+ ? parsed.decision
185
+ : 'revise';
186
+ return {
187
+ decision,
188
+ feedback: typeof parsed.feedback === 'string' ? parsed.feedback : t('common.fallback.noSummary'),
189
+ issues: Array.isArray(parsed.issues)
190
+ ? parsed.issues.filter((v) => typeof v === 'string')
191
+ : [],
192
+ suggestions: Array.isArray(parsed.suggestions)
193
+ ? parsed.suggestions.filter((v) => typeof v === 'string')
194
+ : [],
195
+ };
196
+ }
197
+ catch {
198
+ return null;
199
+ }
200
+ }
201
+ function extractReviewerFromText(text) {
202
+ const lower = text.toLowerCase();
203
+ const decision = lower.includes('approve')
204
+ ? 'approve'
205
+ : lower.includes('reject')
206
+ ? 'reject'
207
+ : 'revise';
208
+ return {
209
+ decision,
210
+ feedback: extractSummary(text),
211
+ issues: [],
212
+ suggestions: [],
213
+ };
214
+ }
215
+ // Helpers
216
+ function findJsonObject(text, marker) {
217
+ const idx = text.indexOf(marker);
218
+ if (idx < 0)
219
+ return null;
220
+ // marker 앞의 '{' 찾기
221
+ let start = text.lastIndexOf('{', idx);
222
+ if (start < 0)
223
+ return null;
224
+ let depth = 0;
225
+ for (let i = start; i < text.length; i++) {
226
+ if (text[i] === '{')
227
+ depth++;
228
+ if (text[i] === '}') {
229
+ depth--;
230
+ if (depth === 0) {
231
+ return text.slice(start, i + 1);
232
+ }
233
+ }
234
+ }
235
+ return null;
236
+ }
237
+ function extractSummary(text) {
238
+ const lines = text.split('\n').filter((l) => l.trim().length > 10);
239
+ if (lines.length === 0)
240
+ return t('common.fallback.noSummary');
241
+ const summary = lines[0].trim();
242
+ return summary.length > 200 ? `${summary.slice(0, 200)}...` : summary;
243
+ }
244
+ function extractErrorMessage(text) {
245
+ const errorMatch = text.match(/(?:error|exception|failed?):\s*(.+)/i);
246
+ if (errorMatch)
247
+ return errorMatch[1].slice(0, 200);
248
+ const lines = text.split('\n').filter((l) => /error|fail/i.test(l));
249
+ return lines.length > 0 ? lines[0].slice(0, 200) : 'Unknown error';
250
+ }
251
+ //# sourceMappingURL=gpt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpt.js","sourceRoot":"","sources":["../../src/adapters/gpt.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,8 @@ export type { CliAdapter, CliRunOptions, CliRunResult, AdapterCapabilities, Adap
2
2
  export { spawnCli } from './base.js';
3
3
  export { ClaudeCliAdapter } from './claude.js';
4
4
  export { CodexCliAdapter } from './codex.js';
5
+ export { GptCliAdapter } from './gpt.js';
6
+ export { LocalModelAdapter } from './local.js';
5
7
  export { registerProcess, getProcess, getAllProcesses, killProcess, startHealthChecker, stopHealthChecker } from './processRegistry.js';
6
8
  import type { AdapterName, CliAdapter } from './types.js';
7
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAKA,YAAY,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIxI,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAS1D;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAuB,GAAG,UAAU,CAMpE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAKzD;AAED,wBAAgB,qBAAqB,IAAI,WAAW,CAEnD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ/D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAKA,YAAY,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAMxI,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAW1D;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAuB,GAAG,UAAU,CAMpE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAKzD;AAED,wBAAgB,qBAAqB,IAAI,WAAW,CAEnD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ/D"}
@@ -5,12 +5,18 @@
5
5
  export { spawnCli } from './base.js';
6
6
  export { ClaudeCliAdapter } from './claude.js';
7
7
  export { CodexCliAdapter } from './codex.js';
8
+ export { GptCliAdapter } from './gpt.js';
9
+ export { LocalModelAdapter } from './local.js';
8
10
  export { registerProcess, getProcess, getAllProcesses, killProcess, startHealthChecker, stopHealthChecker } from './processRegistry.js';
9
11
  import { ClaudeCliAdapter } from './claude.js';
10
12
  import { CodexCliAdapter } from './codex.js';
13
+ import { GptCliAdapter } from './gpt.js';
14
+ import { LocalModelAdapter } from './local.js';
11
15
  const adapters = {
12
16
  claude: new ClaudeCliAdapter(),
13
17
  codex: new CodexCliAdapter(),
18
+ gpt: new GptCliAdapter(),
19
+ local: new LocalModelAdapter(),
14
20
  };
15
21
  let defaultAdapter = 'claude';
16
22
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,mCAAmC;AACnC,kCAAkC;AAClC,+CAA+C;AAa/C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAExI,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,QAAQ,GAA+B;IAC3C,MAAM,EAAE,IAAI,gBAAgB,EAAE;IAC9B,KAAK,EAAE,IAAI,eAAe,EAAE;CAC7B,CAAC;AAEF,IAAI,cAAc,GAAgB,QAAQ,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,cAAc;IACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,mCAAmC;AACnC,kCAAkC;AAClC,+CAA+C;AAa/C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAExI,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,QAAQ,GAA+B;IAC3C,MAAM,EAAE,IAAI,gBAAgB,EAAE;IAC9B,KAAK,EAAE,IAAI,eAAe,EAAE;IAC5B,GAAG,EAAE,IAAI,aAAa,EAAE;IACxB,KAAK,EAAE,IAAI,iBAAiB,EAAE;CAC/B,CAAC;AAEF,IAAI,cAAc,GAAgB,QAAQ,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,cAAc;IACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,cAAc,GAAG,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { CliAdapter, CliRunOptions, CliRunResult, AdapterCapabilities, WorkerResult, ReviewResult } from './types.js';
2
+ export declare class LocalModelAdapter implements CliAdapter {
3
+ readonly name = "local";
4
+ readonly capabilities: AdapterCapabilities;
5
+ private activeUrl;
6
+ private configuredUrl;
7
+ /** config.yaml에서 baseUrl을 주입받을 때 사용 */
8
+ setBaseUrl(url: string): void;
9
+ isAvailable(): Promise<boolean>;
10
+ /** 현재 활성 서버 URL 반환 (디버깅용) */
11
+ getActiveUrl(): string | null;
12
+ /** 사용 가능한 모델 목록 조회 */
13
+ listModels(): Promise<string[]>;
14
+ buildCommand(_options: CliRunOptions): {
15
+ command: string;
16
+ args: string[];
17
+ };
18
+ run(options: CliRunOptions): Promise<CliRunResult>;
19
+ /**
20
+ * 모델의 tool_use 지원 여부 확인
21
+ * Ollama는 일부 모델만 지원 (gemma3, llama3.1+, mistral 등)
22
+ */
23
+ private checkToolSupport;
24
+ /**
25
+ * 로컬 API 호출 함수 생성 (에이전틱 루프에 주입)
26
+ */
27
+ private createApiCaller;
28
+ parseWorkerOutput(raw: CliRunResult): WorkerResult;
29
+ parseReviewerOutput(raw: CliRunResult): ReviewResult;
30
+ }
31
+ //# sourceMappingURL=local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.d.ts","sourceRoot":"","sources":["../../src/adapters/local.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAepB,qBAAa,iBAAkB,YAAW,UAAU;IAClD,QAAQ,CAAC,IAAI,WAAW;IAExB,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAMxC;IAGF,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,aAAa,CAAuB;IAE5C,uCAAuC;IACvC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBrC,6BAA6B;IAC7B,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,sBAAsB;IAChB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBrC,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE;IAIpE,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IA2DxD;;;OAGG;YACW,gBAAgB;IAqC9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoCvB,iBAAiB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;IAKlD,mBAAmB,CAAC,GAAG,EAAE,YAAY,GAAG,YAAY;CAIrD"}
@@ -0,0 +1,320 @@
1
+ // ============================================
2
+ // OpenSwarm - Local Model Adapter
3
+ // Created: 2026-04-10
4
+ // Purpose: Ollama, LMStudio, llama.cpp 등 로컬 OpenAI 호환 서버 지원
5
+ // ============================================
6
+ import { t } from '../locale/index.js';
7
+ import { runAgenticLoop, loopResultToCliResult } from './agenticLoop.js';
8
+ // 로컬 프로바이더 기본 URL 후보 (우선순위 순)
9
+ const DEFAULT_ENDPOINTS = [
10
+ 'http://localhost:11434', // Ollama
11
+ 'http://localhost:1234', // LMStudio
12
+ 'http://localhost:8080', // llama.cpp server
13
+ ];
14
+ const DEFAULT_MODEL = 'gemma3:4b';
15
+ const HEALTH_CHECK_TIMEOUT_MS = 2000;
16
+ export class LocalModelAdapter {
17
+ name = 'local';
18
+ capabilities = {
19
+ supportsStreaming: false,
20
+ supportsJsonOutput: true,
21
+ supportsModelSelection: true,
22
+ managedGit: false,
23
+ supportedSkills: [],
24
+ };
25
+ // 활성 서버 URL (isAvailable에서 감지, run에서 사용)
26
+ activeUrl = null;
27
+ configuredUrl = null;
28
+ /** config.yaml에서 baseUrl을 주입받을 때 사용 */
29
+ setBaseUrl(url) {
30
+ this.configuredUrl = url;
31
+ }
32
+ async isAvailable() {
33
+ const candidates = this.configuredUrl
34
+ ? [this.configuredUrl, ...DEFAULT_ENDPOINTS]
35
+ : DEFAULT_ENDPOINTS;
36
+ for (const url of candidates) {
37
+ try {
38
+ const res = await fetch(`${url}/v1/models`, {
39
+ signal: AbortSignal.timeout(HEALTH_CHECK_TIMEOUT_MS),
40
+ });
41
+ if (res.ok) {
42
+ this.activeUrl = url;
43
+ return true;
44
+ }
45
+ }
46
+ catch {
47
+ // 서버 미실행 — 다음 후보로
48
+ }
49
+ }
50
+ return false;
51
+ }
52
+ /** 현재 활성 서버 URL 반환 (디버깅용) */
53
+ getActiveUrl() {
54
+ return this.activeUrl;
55
+ }
56
+ /** 사용 가능한 모델 목록 조회 */
57
+ async listModels() {
58
+ if (!this.activeUrl) {
59
+ const available = await this.isAvailable();
60
+ if (!available)
61
+ return [];
62
+ }
63
+ try {
64
+ const res = await fetch(`${this.activeUrl}/v1/models`, {
65
+ signal: AbortSignal.timeout(HEALTH_CHECK_TIMEOUT_MS),
66
+ });
67
+ if (!res.ok)
68
+ return [];
69
+ const data = (await res.json());
70
+ return data.data?.map(m => m.id) ?? [];
71
+ }
72
+ catch {
73
+ return [];
74
+ }
75
+ }
76
+ buildCommand(_options) {
77
+ return { command: 'echo', args: ['"Local adapter uses run() — not shell spawn"'] };
78
+ }
79
+ async run(options) {
80
+ const startTime = Date.now();
81
+ // 서버 연결 확인
82
+ if (!this.activeUrl) {
83
+ const available = await this.isAvailable();
84
+ if (!available) {
85
+ return {
86
+ exitCode: 1,
87
+ stdout: '',
88
+ stderr: 'No local model server found. Start Ollama, LMStudio, or llama.cpp server first.\n' +
89
+ `Checked: ${(this.configuredUrl ? [this.configuredUrl, ...DEFAULT_ENDPOINTS] : DEFAULT_ENDPOINTS).join(', ')}`,
90
+ durationMs: Date.now() - startTime,
91
+ };
92
+ }
93
+ }
94
+ const model = options.model ?? DEFAULT_MODEL;
95
+ const baseUrl = this.activeUrl;
96
+ // 도구 지원 여부 감지 (모델에 따라 다를 수 있음)
97
+ const supportsTools = await this.checkToolSupport(baseUrl, model);
98
+ // 에이전틱 루프로 실행
99
+ const callApi = this.createApiCaller(baseUrl, model);
100
+ const loopOptions = {
101
+ prompt: options.prompt,
102
+ cwd: options.cwd ?? process.cwd(),
103
+ model,
104
+ callApi,
105
+ maxTurns: options.maxTurns ?? 15,
106
+ timeoutMs: options.timeoutMs || 300000,
107
+ onLog: options.onLog,
108
+ enableTools: supportsTools,
109
+ };
110
+ try {
111
+ const result = await runAgenticLoop(loopOptions);
112
+ if (options.onLog) {
113
+ const toolInfo = supportsTools ? `${result.toolCallCount} tool uses` : 'no tools';
114
+ options.onLog(`[Local] ${result.apiCallCount} API calls, ${toolInfo}, ${result.totalTokens} tokens`);
115
+ }
116
+ return loopResultToCliResult(result);
117
+ }
118
+ catch (err) {
119
+ const message = err instanceof Error ? err.message : String(err);
120
+ const isTimeout = message.includes('abort') || message.includes('timeout');
121
+ return {
122
+ exitCode: 1,
123
+ stdout: '',
124
+ stderr: isTimeout
125
+ ? `Local model timeout after ${options.timeoutMs ?? 300000}ms (model: ${model}). Local models can be slow — consider increasing timeout.`
126
+ : `Local model request failed: ${message}`,
127
+ durationMs: Date.now() - startTime,
128
+ };
129
+ }
130
+ }
131
+ /**
132
+ * 모델의 tool_use 지원 여부 확인
133
+ * Ollama는 일부 모델만 지원 (gemma3, llama3.1+, mistral 등)
134
+ */
135
+ async checkToolSupport(baseUrl, model) {
136
+ // 알려진 tool_use 지원 모델 패턴
137
+ const toolCapablePatterns = [
138
+ /^llama3\.[1-9]/, // llama3.1+
139
+ /^gemma/, // gemma 계열
140
+ /^mistral/, // mistral
141
+ /^qwen/, // qwen
142
+ /^command-r/, // cohere command-r
143
+ /^firefunction/, // fireworks
144
+ /^hermes/, // hermes
145
+ ];
146
+ const modelLower = model.toLowerCase();
147
+ const knownCapable = toolCapablePatterns.some(p => p.test(modelLower));
148
+ if (knownCapable)
149
+ return true;
150
+ // 알 수 없는 모델 → 1회 probe 시도
151
+ try {
152
+ const res = await fetch(`${baseUrl}/v1/chat/completions`, {
153
+ method: 'POST',
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: JSON.stringify({
156
+ model,
157
+ messages: [{ role: 'user', content: 'hi' }],
158
+ tools: [{ type: 'function', function: { name: 'test', description: 'test', parameters: { type: 'object', properties: {} } } }],
159
+ max_tokens: 1,
160
+ }),
161
+ signal: AbortSignal.timeout(5000),
162
+ });
163
+ // 200이면 tool 지원, 에러면 미지원
164
+ return res.ok;
165
+ }
166
+ catch {
167
+ return false;
168
+ }
169
+ }
170
+ /**
171
+ * 로컬 API 호출 함수 생성 (에이전틱 루프에 주입)
172
+ */
173
+ createApiCaller(baseUrl, model) {
174
+ return async (messages, tools) => {
175
+ const body = {
176
+ model,
177
+ messages,
178
+ temperature: 0.2,
179
+ stream: false,
180
+ };
181
+ if (tools.length > 0) {
182
+ body.tools = tools;
183
+ }
184
+ const res = await fetch(`${baseUrl}/v1/chat/completions`, {
185
+ method: 'POST',
186
+ headers: { 'Content-Type': 'application/json' },
187
+ body: JSON.stringify(body),
188
+ });
189
+ if (!res.ok) {
190
+ const errText = await res.text().catch(() => '');
191
+ if (res.status === 404 || errText.includes('not found')) {
192
+ const models = await this.listModels();
193
+ const modelList = models.length > 0
194
+ ? `Available: ${models.slice(0, 10).join(', ')}`
195
+ : 'No models loaded';
196
+ throw new Error(`Model "${model}" not found on ${baseUrl}. ${modelList}`);
197
+ }
198
+ throw new Error(`Local API error (${res.status}): ${errText.slice(0, 500)}`);
199
+ }
200
+ return (await res.json());
201
+ };
202
+ }
203
+ parseWorkerOutput(raw) {
204
+ const text = raw.stdout;
205
+ return extractWorkerResultJson(text) ?? extractWorkerFromText(text);
206
+ }
207
+ parseReviewerOutput(raw) {
208
+ const text = raw.stdout;
209
+ return extractReviewerResultJson(text) ?? extractReviewerFromText(text);
210
+ }
211
+ }
212
+ // Worker/Reviewer 출력 파싱 (GPT 어댑터와 동일 로직)
213
+ function extractWorkerResultJson(text) {
214
+ const jsonMatch = text.match(/```json\s*([\s\S]*?)\s*```/);
215
+ const jsonStr = jsonMatch?.[1] ?? findJsonObject(text, '"success"');
216
+ if (!jsonStr)
217
+ return null;
218
+ try {
219
+ const parsed = JSON.parse(jsonStr);
220
+ return {
221
+ success: Boolean(parsed.success),
222
+ summary: parsed.summary || t('common.fallback.noSummary'),
223
+ filesChanged: Array.isArray(parsed.filesChanged) ? parsed.filesChanged : [],
224
+ commands: Array.isArray(parsed.commands) ? parsed.commands : [],
225
+ output: text,
226
+ error: parsed.error,
227
+ confidencePercent: typeof parsed.confidencePercent === 'number'
228
+ ? parsed.confidencePercent : undefined,
229
+ haltReason: parsed.haltReason || undefined,
230
+ };
231
+ }
232
+ catch {
233
+ return null;
234
+ }
235
+ }
236
+ function extractWorkerFromText(text) {
237
+ const hasError = /error|fail|exception|cannot/i.test(text);
238
+ const hasSuccess = /success|completed|done|finished/i.test(text);
239
+ return {
240
+ success: !hasError || hasSuccess,
241
+ summary: extractSummary(text),
242
+ filesChanged: [],
243
+ commands: [],
244
+ output: text,
245
+ error: hasError ? extractErrorMessage(text) : undefined,
246
+ };
247
+ }
248
+ function extractReviewerResultJson(text) {
249
+ const jsonMatch = text.match(/```json\s*([\s\S]*?)\s*```/);
250
+ const jsonStr = jsonMatch?.[1] ?? findJsonObject(text, '"decision"');
251
+ if (!jsonStr)
252
+ return null;
253
+ try {
254
+ const parsed = JSON.parse(jsonStr);
255
+ const decision = parsed.decision === 'approve' || parsed.decision === 'reject'
256
+ ? parsed.decision
257
+ : 'revise';
258
+ return {
259
+ decision,
260
+ feedback: typeof parsed.feedback === 'string' ? parsed.feedback : t('common.fallback.noSummary'),
261
+ issues: Array.isArray(parsed.issues)
262
+ ? parsed.issues.filter((v) => typeof v === 'string')
263
+ : [],
264
+ suggestions: Array.isArray(parsed.suggestions)
265
+ ? parsed.suggestions.filter((v) => typeof v === 'string')
266
+ : [],
267
+ };
268
+ }
269
+ catch {
270
+ return null;
271
+ }
272
+ }
273
+ function extractReviewerFromText(text) {
274
+ const lower = text.toLowerCase();
275
+ const decision = lower.includes('approve')
276
+ ? 'approve'
277
+ : lower.includes('reject')
278
+ ? 'reject'
279
+ : 'revise';
280
+ return {
281
+ decision,
282
+ feedback: extractSummary(text),
283
+ issues: [],
284
+ suggestions: [],
285
+ };
286
+ }
287
+ function findJsonObject(text, marker) {
288
+ const idx = text.indexOf(marker);
289
+ if (idx < 0)
290
+ return null;
291
+ let start = text.lastIndexOf('{', idx);
292
+ if (start < 0)
293
+ return null;
294
+ let depth = 0;
295
+ for (let i = start; i < text.length; i++) {
296
+ if (text[i] === '{')
297
+ depth++;
298
+ if (text[i] === '}') {
299
+ depth--;
300
+ if (depth === 0)
301
+ return text.slice(start, i + 1);
302
+ }
303
+ }
304
+ return null;
305
+ }
306
+ function extractSummary(text) {
307
+ const lines = text.split('\n').filter(l => l.trim().length > 10);
308
+ if (lines.length === 0)
309
+ return t('common.fallback.noSummary');
310
+ const summary = lines[0].trim();
311
+ return summary.length > 200 ? `${summary.slice(0, 200)}...` : summary;
312
+ }
313
+ function extractErrorMessage(text) {
314
+ const errorMatch = text.match(/(?:error|exception|failed?):\s*(.+)/i);
315
+ if (errorMatch)
316
+ return errorMatch[1].slice(0, 200);
317
+ const lines = text.split('\n').filter(l => /error|fail/i.test(l));
318
+ return lines.length > 0 ? lines[0].slice(0, 200) : 'Unknown error';
319
+ }
320
+ //# sourceMappingURL=local.js.map