@mulsok/traders-client 0.1.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 (119) hide show
  1. package/README.md +103 -0
  2. package/bin/cli.js +160 -0
  3. package/bin/postinstall.js +57 -0
  4. package/bin/preuninstall.js +36 -0
  5. package/dist/server/broker/kiwoom/cache.js +86 -0
  6. package/dist/server/broker/kiwoom/cache.js.map +1 -0
  7. package/dist/server/broker/kiwoom/client.js +256 -0
  8. package/dist/server/broker/kiwoom/client.js.map +1 -0
  9. package/dist/server/broker/kiwoom/endpoints/_helpers.js +61 -0
  10. package/dist/server/broker/kiwoom/endpoints/_helpers.js.map +1 -0
  11. package/dist/server/broker/kiwoom/endpoints/account.js +448 -0
  12. package/dist/server/broker/kiwoom/endpoints/account.js.map +1 -0
  13. package/dist/server/broker/kiwoom/endpoints/detail.js +118 -0
  14. package/dist/server/broker/kiwoom/endpoints/detail.js.map +1 -0
  15. package/dist/server/broker/kiwoom/endpoints/investor.js +139 -0
  16. package/dist/server/broker/kiwoom/endpoints/investor.js.map +1 -0
  17. package/dist/server/broker/kiwoom/endpoints/order.js +134 -0
  18. package/dist/server/broker/kiwoom/endpoints/order.js.map +1 -0
  19. package/dist/server/broker/kiwoom/endpoints/quote.js +165 -0
  20. package/dist/server/broker/kiwoom/endpoints/quote.js.map +1 -0
  21. package/dist/server/broker/kiwoom/endpoints/ranking.js +180 -0
  22. package/dist/server/broker/kiwoom/endpoints/ranking.js.map +1 -0
  23. package/dist/server/broker/kiwoom/endpoints/sector.js +135 -0
  24. package/dist/server/broker/kiwoom/endpoints/sector.js.map +1 -0
  25. package/dist/server/broker/kiwoom/endpoints/theme.js +104 -0
  26. package/dist/server/broker/kiwoom/endpoints/theme.js.map +1 -0
  27. package/dist/server/broker/kiwoom/endpoints/universe.js +119 -0
  28. package/dist/server/broker/kiwoom/endpoints/universe.js.map +1 -0
  29. package/dist/server/broker/kiwoom/index.js +59 -0
  30. package/dist/server/broker/kiwoom/index.js.map +1 -0
  31. package/dist/server/broker/kiwoom/order-tracker.js +353 -0
  32. package/dist/server/broker/kiwoom/order-tracker.js.map +1 -0
  33. package/dist/server/broker/kiwoom/price-feed.js +119 -0
  34. package/dist/server/broker/kiwoom/price-feed.js.map +1 -0
  35. package/dist/server/broker/kiwoom/rate-limiter.js +97 -0
  36. package/dist/server/broker/kiwoom/rate-limiter.js.map +1 -0
  37. package/dist/server/broker/kiwoom/types.js +13 -0
  38. package/dist/server/broker/kiwoom/types.js.map +1 -0
  39. package/dist/server/broker/kiwoom/ws/client.js +370 -0
  40. package/dist/server/broker/kiwoom/ws/client.js.map +1 -0
  41. package/dist/server/broker/kiwoom/ws/endpoints/condition.js +146 -0
  42. package/dist/server/broker/kiwoom/ws/endpoints/condition.js.map +1 -0
  43. package/dist/server/broker/kiwoom/ws/realtime-bus.js +42 -0
  44. package/dist/server/broker/kiwoom/ws/realtime-bus.js.map +1 -0
  45. package/dist/server/broker/kiwoom/ws/types.js +19 -0
  46. package/dist/server/broker/kiwoom/ws/types.js.map +1 -0
  47. package/dist/server/broker/news.js +34 -0
  48. package/dist/server/broker/news.js.map +1 -0
  49. package/dist/server/bundle.js +43 -0
  50. package/dist/server/bundle.js.map +1 -0
  51. package/dist/server/calendar/krx-holidays.js +162 -0
  52. package/dist/server/calendar/krx-holidays.js.map +1 -0
  53. package/dist/server/config.js +263 -0
  54. package/dist/server/config.js.map +1 -0
  55. package/dist/server/db/sqlite.js +252 -0
  56. package/dist/server/db/sqlite.js.map +1 -0
  57. package/dist/server/diary/writer.js +266 -0
  58. package/dist/server/diary/writer.js.map +1 -0
  59. package/dist/server/index.js +316 -0
  60. package/dist/server/index.js.map +1 -0
  61. package/dist/server/jobs/universe-sync.js +132 -0
  62. package/dist/server/jobs/universe-sync.js.map +1 -0
  63. package/dist/server/jobs/watchdog.js +87 -0
  64. package/dist/server/jobs/watchdog.js.map +1 -0
  65. package/dist/server/journal/pnl-stats.js +108 -0
  66. package/dist/server/journal/pnl-stats.js.map +1 -0
  67. package/dist/server/journal/telemetry.js +174 -0
  68. package/dist/server/journal/telemetry.js.map +1 -0
  69. package/dist/server/journal/trade-journal.js +239 -0
  70. package/dist/server/journal/trade-journal.js.map +1 -0
  71. package/dist/server/llm/anthropic.js +98 -0
  72. package/dist/server/llm/anthropic.js.map +1 -0
  73. package/dist/server/llm/claude-cli.js +204 -0
  74. package/dist/server/llm/claude-cli.js.map +1 -0
  75. package/dist/server/llm/context-builder.js +229 -0
  76. package/dist/server/llm/context-builder.js.map +1 -0
  77. package/dist/server/llm/gemini.js +86 -0
  78. package/dist/server/llm/gemini.js.map +1 -0
  79. package/dist/server/llm/index.js +36 -0
  80. package/dist/server/llm/index.js.map +1 -0
  81. package/dist/server/llm/openai.js +87 -0
  82. package/dist/server/llm/openai.js.map +1 -0
  83. package/dist/server/personas/executor.js +318 -0
  84. package/dist/server/personas/executor.js.map +1 -0
  85. package/dist/server/personas/loader.js +165 -0
  86. package/dist/server/personas/loader.js.map +1 -0
  87. package/dist/server/personas/persona-agent.js +386 -0
  88. package/dist/server/personas/persona-agent.js.map +1 -0
  89. package/dist/server/personas/persona-state.js +170 -0
  90. package/dist/server/personas/persona-state.js.map +1 -0
  91. package/dist/server/personas/runner.js +162 -0
  92. package/dist/server/personas/runner.js.map +1 -0
  93. package/dist/server/personas/schema.js +123 -0
  94. package/dist/server/personas/schema.js.map +1 -0
  95. package/dist/server/personas/wake-plan.js +313 -0
  96. package/dist/server/personas/wake-plan.js.map +1 -0
  97. package/dist/server/readiness.js +414 -0
  98. package/dist/server/readiness.js.map +1 -0
  99. package/dist/server/routes.js +1216 -0
  100. package/dist/server/routes.js.map +1 -0
  101. package/dist/server/safety.js +153 -0
  102. package/dist/server/safety.js.map +1 -0
  103. package/dist/server/screener/engine.js +856 -0
  104. package/dist/server/screener/engine.js.map +1 -0
  105. package/dist/server/server-sync.js +427 -0
  106. package/dist/server/server-sync.js.map +1 -0
  107. package/dist/server/signing.js +39 -0
  108. package/dist/server/signing.js.map +1 -0
  109. package/dist/server/watchers/condition-watcher.js +519 -0
  110. package/dist/server/watchers/condition-watcher.js.map +1 -0
  111. package/dist/server/watchers/types.js +16 -0
  112. package/dist/server/watchers/types.js.map +1 -0
  113. package/dist/web/assets/index-62SMpbaf.js +79 -0
  114. package/dist/web/assets/index-BPLQR0wt.css +1 -0
  115. package/dist/web/index.html +14 -0
  116. package/package.json +93 -0
  117. package/scripts/com.mulsok.traders.client.plist.template +58 -0
  118. package/scripts/install-daemon.sh +156 -0
  119. package/scripts/uninstall-daemon.sh +62 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Claude CLI Provider · taeeun-life/agent-server/src/claude-cli.ts 레퍼런스.
3
+ *
4
+ * Anthropic API key 없이 **Claude Code 구독** 만으로 작동 (Max/Team 플랜).
5
+ * 시스템에 `claude` 바이너리가 설치돼 있어야 함.
6
+ *
7
+ * 호출:
8
+ * claude --dangerously-skip-permissions -p "<user prompt>" \
9
+ * --output-format json --model <sonnet|opus|haiku> \
10
+ * --system-prompt "<system>"
11
+ */
12
+ import { spawn } from "node:child_process";
13
+ /**
14
+ * Claude CLI subprocess timeout (사용자 정정 · 2026-05-03).
15
+ *
16
+ * 사용자 의도: timeout 으로 답변 도중 끊기면 재호출 비용 더 큼 → 충분히 길게.
17
+ * 기본 30분 (sonnet extended thinking + tool use 도 안전).
18
+ * 환경 변수 `CLAUDE_CLI_TIMEOUT_SEC` 로 override 가능 (운영 중 조정).
19
+ *
20
+ * spawnSafe 가 timeout 도달 시 SIGTERM kill — 이 시점에서 stdout 텍스트 손실 + 비용은 이미 발생.
21
+ * 그래서 default 가 충분히 커야 함.
22
+ */
23
+ const DEFAULT_TIMEOUT_SEC = (() => {
24
+ const env = process.env.CLAUDE_CLI_TIMEOUT_SEC;
25
+ if (env && /^\d+$/.test(env)) {
26
+ const n = Number(env);
27
+ if (n >= 60 && n <= 3600)
28
+ return n; // 1분~1시간 사이만 허용 (오타 보호)
29
+ }
30
+ return 30 * 60; // 기본 30분
31
+ })();
32
+ export function createClaudeCliProvider(opts) {
33
+ const binary = opts.binaryPath ?? "claude";
34
+ return {
35
+ kind: "claude-cli",
36
+ async test() {
37
+ try {
38
+ const version = await runVersion(binary);
39
+ return {
40
+ ok: true,
41
+ provider: "claude-cli",
42
+ model: opts.model,
43
+ detail: `감지됨 · ${version}`,
44
+ };
45
+ }
46
+ catch (e) {
47
+ return {
48
+ ok: false,
49
+ provider: "claude-cli",
50
+ error: `Claude CLI 미설치 또는 실행 실패 · ${String(e)}`,
51
+ };
52
+ }
53
+ },
54
+ async complete(c) {
55
+ // 프로젝트 루트 (.claude/skills 위치 = mulsok-traders).
56
+ // tsx watch 의 cwd 가 mulsok-traders 인 가정 (monorepo root).
57
+ // 다르면 사용자 환경변수 MULSOK_PROJECT_ROOT 로 override.
58
+ const projectRoot = process.env.MULSOK_PROJECT_ROOT ?? process.cwd();
59
+ const args = [
60
+ "--dangerously-skip-permissions",
61
+ // Skills 인식 + helper script 실행 권한
62
+ "--add-dir", projectRoot,
63
+ "-p",
64
+ c.userPrompt,
65
+ "--output-format",
66
+ "json",
67
+ "--model",
68
+ opts.model,
69
+ ];
70
+ if (c.systemPrompt) {
71
+ args.push("--system-prompt", c.systemPrompt);
72
+ }
73
+ const { stdout } = await runClaude(binary, args, DEFAULT_TIMEOUT_SEC);
74
+ // Claude Code 2.x 의 JSON output 은 이벤트 배열 스트림 or 단일 객체.
75
+ // 우리가 원하는 "마지막 assistant message" 추출.
76
+ const text = extractAssistantText(stdout);
77
+ // claude-cli 는 finish_reason 노출 안 함 (subprocess wrapper).
78
+ // 추출 텍스트가 비어있으면 의심 (실패 케이스 다른 곳에서 throw).
79
+ return {
80
+ text,
81
+ model: opts.model,
82
+ provider: "claude-cli",
83
+ stopReason: text ? "stop" : "unknown",
84
+ raw: stdout,
85
+ };
86
+ },
87
+ };
88
+ }
89
+ async function runVersion(binary) {
90
+ const { stdout } = await spawnSafe(binary, ["--version"], 10);
91
+ return stdout.trim();
92
+ }
93
+ async function runClaude(binary, args, timeoutSec) {
94
+ // Claude 관련 env (CLAUDE_*) 는 inherit 금지 (taeeun-life 패턴)
95
+ const env = Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith("CLAUDE")));
96
+ return spawnSafe(binary, args, timeoutSec, env);
97
+ }
98
+ function spawnSafe(binary, args, timeoutSec, env) {
99
+ return new Promise((resolve, reject) => {
100
+ const child = spawn(binary, args, {
101
+ env: env ?? process.env,
102
+ stdio: ["ignore", "pipe", "pipe"],
103
+ });
104
+ let stdout = "";
105
+ let stderr = "";
106
+ let killed = false;
107
+ const timer = setTimeout(() => {
108
+ killed = true;
109
+ try {
110
+ child.kill("SIGTERM");
111
+ }
112
+ catch {
113
+ /* ignore */
114
+ }
115
+ }, timeoutSec * 1000);
116
+ child.stdout.on("data", (d) => {
117
+ stdout += d.toString("utf-8");
118
+ });
119
+ child.stderr.on("data", (d) => {
120
+ stderr += d.toString("utf-8");
121
+ });
122
+ child.on("error", (e) => {
123
+ clearTimeout(timer);
124
+ reject(e);
125
+ });
126
+ child.on("close", (code) => {
127
+ clearTimeout(timer);
128
+ if (killed)
129
+ return reject(new Error(`Claude CLI 타임아웃 (${timeoutSec}s)`));
130
+ if (code !== 0 && code !== null) {
131
+ return reject(new Error(`Claude CLI exit ${code}: ${stderr.slice(0, 200)}`));
132
+ }
133
+ resolve({ stdout, stderr });
134
+ });
135
+ });
136
+ }
137
+ /**
138
+ * Claude CLI --output-format json 의 결과 파싱.
139
+ * 2.x: 단일 JSON 객체 또는 줄바꿈 구분 이벤트 배열. 본문 텍스트 추출.
140
+ */
141
+ function extractAssistantText(stdout) {
142
+ // 1) single object 시도
143
+ const trimmed = stdout.trim();
144
+ try {
145
+ const obj = JSON.parse(trimmed);
146
+ if (typeof obj === "object" && obj !== null) {
147
+ // shape 예:
148
+ // { result: "...", session_id, messages: [...] }
149
+ // 또는 { content: [{type:"text", text:"..."}] }
150
+ // 또는 messages 배열의 마지막 assistant message
151
+ if (typeof obj.result === "string") {
152
+ return obj.result;
153
+ }
154
+ const content = obj.content;
155
+ if (Array.isArray(content)) {
156
+ return content.map((b) => (b.type === "text" ? b.text ?? "" : "")).join("");
157
+ }
158
+ const messages = obj.messages;
159
+ if (Array.isArray(messages)) {
160
+ for (let i = messages.length - 1; i >= 0; i--) {
161
+ const m = messages[i];
162
+ if (m.role === "assistant") {
163
+ if (typeof m.content === "string")
164
+ return m.content;
165
+ if (Array.isArray(m.content)) {
166
+ return m.content
167
+ .map((b) => (b.type === "text" ? b.text ?? "" : ""))
168
+ .join("");
169
+ }
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ catch {
176
+ // 2) line-delimited 이벤트 스트림 시도
177
+ const lines = stdout.split("\n").filter((l) => l.trim());
178
+ for (let i = lines.length - 1; i >= 0; i--) {
179
+ try {
180
+ const ev = JSON.parse(lines[i]);
181
+ if (ev.type === "assistant" || ev.type === "message") {
182
+ if (typeof ev.text === "string")
183
+ return ev.text;
184
+ if (ev.message && typeof ev.message === "object") {
185
+ const mc = ev.message.content;
186
+ if (typeof mc === "string")
187
+ return mc;
188
+ if (Array.isArray(mc)) {
189
+ return mc
190
+ .map((b) => (b.type === "text" ? b.text ?? "" : ""))
191
+ .join("");
192
+ }
193
+ }
194
+ }
195
+ }
196
+ catch {
197
+ /* skip */
198
+ }
199
+ }
200
+ }
201
+ // fallback: raw
202
+ return stdout.slice(0, 4000);
203
+ }
204
+ //# sourceMappingURL=claude-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-cli.js","sourceRoot":"","sources":["../../../src-server/llm/claude-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Layer 3 Context Builder (apps/client)
3
+ *
4
+ * 책임: LLM 호출 시 Layer 3 (사용자 저널) 부분 자동 조합
5
+ *
6
+ * 입력:
7
+ * - personaSlug · 어떤 페르소나 컨텍스트
8
+ * - 보유 종목 (account.getHoldings)
9
+ * - 활성 watcher (ConditionWatcher.list)
10
+ * - 활성 미체결 주문 (OrderTracker.list)
11
+ * - 최근 lessons (trade-journal · 직전 N건)
12
+ * - 시장 지수 (코스피/코스닥)
13
+ *
14
+ * 출력: layer3Header (string) · LLM 에 system prompt 마지막에 들어감
15
+ *
16
+ * Context 절약 전략 (사용자 5번 질문):
17
+ * - 보유 + 관심 (watcher 등록 종목) 만 포함
18
+ * - 전체 종목 데이터는 보내지 않음
19
+ * - lessons 는 최신 5건만
20
+ * - 인덱스 데이터는 한 줄 요약
21
+ */
22
+ import fs from "node:fs";
23
+ import path from "node:path";
24
+ import os from "node:os";
25
+ import { getHoldings, getMarketIndex } from "../broker/kiwoom/index.js";
26
+ import { getConditionWatcher } from "../watchers/condition-watcher.js";
27
+ import { getOrderTracker } from "../broker/kiwoom/order-tracker.js";
28
+ import { readEvents } from "../journal/trade-journal.js";
29
+ /**
30
+ * Layer 3 patches 디렉토리 (Coach 가 출력한 patch 파일 모음)
31
+ *
32
+ * 구조:
33
+ * ~/.mulsok-traders/layer3-patches/<personaSlug>/<yyyy-mm-dd>-<idx>.md
34
+ *
35
+ * Coach 가 patch 를 발행 (P15+ executor) → 사용자가 승인 → 이 디렉토리에 markdown 파일로 저장.
36
+ * buildLayer3Patches() 가 자동 reload 해서 LLM context 에 주입.
37
+ */
38
+ const PATCHES_DIR = path.join(os.homedir(), ".mulsok-traders", "layer3-patches");
39
+ /** 활성 patch 모음 · markdown 합쳐서 반환 */
40
+ export function loadActivePatches(personaSlug) {
41
+ const personaDir = path.join(PATCHES_DIR, personaSlug);
42
+ if (!fs.existsSync(personaDir))
43
+ return "";
44
+ const files = fs
45
+ .readdirSync(personaDir)
46
+ .filter((f) => f.endsWith(".md"))
47
+ .sort();
48
+ if (files.length === 0)
49
+ return "";
50
+ const sections = [];
51
+ for (const f of files) {
52
+ try {
53
+ const text = fs.readFileSync(path.join(personaDir, f), "utf-8");
54
+ sections.push(`<!-- patch: ${f} -->\n${text.trim()}`);
55
+ }
56
+ catch {
57
+ // skip
58
+ }
59
+ }
60
+ return sections.join("\n\n---\n\n");
61
+ }
62
+ /**
63
+ * Layer3 컨텍스트 데이터 수집 (raw 객체 반환 · 마크다운 X).
64
+ *
65
+ * - 외부 API (kiwoom · 시장 지수 · 보유) 모두 1회씩만 호출
66
+ * - 실패 시 null 또는 빈 배열 fallback (throw 없음)
67
+ *
68
+ * 호출자:
69
+ * - formatLayer3Markdown() · LLM prompt 용
70
+ * - executor.ts · journal layer3_snapshot 저장 용
71
+ *
72
+ * 두 곳에서 같은 collect 결과를 공유하면 외부 API 중복 호출 없음.
73
+ */
74
+ export async function collectLayer3Snapshot(opts) {
75
+ const { personaSlug, maxLessons = 5, includeMarketIndex = true, includeHoldings = true, includeWatchers = true, includePendingOrders = true, } = opts;
76
+ const snapshot = {
77
+ capturedAt: new Date().toISOString(),
78
+ personaSlug,
79
+ };
80
+ if (includeMarketIndex) {
81
+ const [kospi, kosdaq] = await Promise.all([
82
+ getMarketIndex("kospi").catch(() => null),
83
+ getMarketIndex("kosdaq").catch(() => null),
84
+ ]);
85
+ snapshot.marketIndex = {
86
+ kospi: kospi?.ok ? { currentValue: kospi.data.currentValue, changePct: kospi.data.changePct } : null,
87
+ kosdaq: kosdaq?.ok ? { currentValue: kosdaq.data.currentValue, changePct: kosdaq.data.changePct } : null,
88
+ };
89
+ }
90
+ if (includeHoldings) {
91
+ try {
92
+ const holdingsRes = await getHoldings();
93
+ if (holdingsRes.ok) {
94
+ snapshot.holdings = {
95
+ items: holdingsRes.data.items.map((h) => ({
96
+ symbolCode: h.symbolCode,
97
+ symbolName: h.symbolName,
98
+ quantity: h.quantity,
99
+ avgBuyPriceKrw: h.avgBuyPriceKrw,
100
+ currentPriceKrw: h.currentPriceKrw,
101
+ pnlPct: h.pnlPct,
102
+ })),
103
+ totalEvalKrw: holdingsRes.data.totalEvalKrw,
104
+ totalPnlKrw: holdingsRes.data.totalPnlKrw,
105
+ totalPnlPct: holdingsRes.data.totalPnlPct,
106
+ };
107
+ }
108
+ else {
109
+ snapshot.holdings = null;
110
+ }
111
+ }
112
+ catch {
113
+ snapshot.holdings = null;
114
+ }
115
+ }
116
+ if (includePendingOrders) {
117
+ const orders = getOrderTracker().list({ activeOnly: true }).filter((o) => o.personaSlug === personaSlug);
118
+ snapshot.pendingOrders = orders.map((o) => ({
119
+ symbolCode: o.symbolCode,
120
+ side: o.side,
121
+ intendedQty: o.intendedQty,
122
+ intendedPriceKrw: o.intendedPriceKrw,
123
+ status: o.status,
124
+ filledQty: o.filledQty,
125
+ }));
126
+ }
127
+ if (includeWatchers) {
128
+ const watchers = getConditionWatcher().list({ personaSlug, activeOnly: true });
129
+ snapshot.activeWatchers = watchers.map((w) => ({
130
+ id: w.id,
131
+ type: w.spec.condition.type,
132
+ intent: w.spec.intent,
133
+ expiresAt: w.expiresAt,
134
+ triggerCount: w.triggerCount,
135
+ }));
136
+ }
137
+ // 최근 lessons (decision 이벤트의 llmContext.lesson)
138
+ const recentEvents = readEvents({
139
+ personaSlug,
140
+ eventTypes: ["decision"],
141
+ limit: maxLessons * 3,
142
+ });
143
+ snapshot.recentLessons = recentEvents
144
+ .filter((e) => e.llmContext?.lesson)
145
+ .slice(0, maxLessons)
146
+ .map((e) => ({
147
+ time: e.timestamp.slice(0, 16),
148
+ symbolCode: e.symbolCode,
149
+ lesson: e.llmContext?.lesson,
150
+ }));
151
+ return snapshot;
152
+ }
153
+ /**
154
+ * 스냅샷을 LLM prompt 마크다운으로 변환 (외부 API 호출 X · 순수).
155
+ */
156
+ export function formatLayer3Markdown(snap) {
157
+ const sections = [];
158
+ sections.push(`# Layer 3 · 사용자 컨텍스트 (persona: ${snap.personaSlug} · ${snap.capturedAt.slice(0, 19)})`);
159
+ if (snap.marketIndex) {
160
+ const lines = ["## 시장 분위기"];
161
+ if (snap.marketIndex.kospi) {
162
+ lines.push(`- KOSPI ${snap.marketIndex.kospi.currentValue.toLocaleString()} (${fmtPct(snap.marketIndex.kospi.changePct)})`);
163
+ }
164
+ else {
165
+ lines.push("- KOSPI 조회 실패");
166
+ }
167
+ if (snap.marketIndex.kosdaq) {
168
+ lines.push(`- KOSDAQ ${snap.marketIndex.kosdaq.currentValue.toLocaleString()} (${fmtPct(snap.marketIndex.kosdaq.changePct)})`);
169
+ }
170
+ else {
171
+ lines.push("- KOSDAQ 조회 실패");
172
+ }
173
+ sections.push(lines.join("\n"));
174
+ }
175
+ if (snap.holdings !== undefined) {
176
+ const lines = ["## 현재 보유 종목"];
177
+ if (snap.holdings && snap.holdings.items.length > 0) {
178
+ for (const h of snap.holdings.items) {
179
+ lines.push(`- ${h.symbolName} (${h.symbolCode}) · ${h.quantity}주 · 평균 ${h.avgBuyPriceKrw.toLocaleString()}원 · 현재 ${h.currentPriceKrw.toLocaleString()}원 · 평가 ${fmtPct(h.pnlPct)}`);
180
+ }
181
+ lines.push(`- 총 평가 ${snap.holdings.totalEvalKrw.toLocaleString()}원 · 손익 ${snap.holdings.totalPnlKrw.toLocaleString()}원 (${fmtPct(snap.holdings.totalPnlPct)})`);
182
+ }
183
+ else {
184
+ lines.push("- 보유 종목 없음");
185
+ }
186
+ sections.push(lines.join("\n"));
187
+ }
188
+ if (snap.pendingOrders && snap.pendingOrders.length > 0) {
189
+ const lines = ["## 활성 미체결 주문 (이 페르소나)"];
190
+ for (const o of snap.pendingOrders) {
191
+ lines.push(`- ${o.symbolCode} · ${o.side} ${o.intendedQty}주 @ ${o.intendedPriceKrw.toLocaleString()}원 · ${o.status} · 체결 ${o.filledQty}/${o.intendedQty}`);
192
+ }
193
+ lines.push("⚠️ 같은 종목 신규 주문은 OrderTracker 가 자동 거부합니다 (중복 방지).");
194
+ sections.push(lines.join("\n"));
195
+ }
196
+ if (snap.activeWatchers && snap.activeWatchers.length > 0) {
197
+ const lines = ["## 활성 감시자 (wake_plan.watchers)"];
198
+ for (const w of snap.activeWatchers) {
199
+ lines.push(`- [${w.type}] ${w.intent} · 만료 ${w.expiresAt.slice(0, 19)}`);
200
+ }
201
+ sections.push(lines.join("\n"));
202
+ }
203
+ if (snap.recentLessons && snap.recentLessons.length > 0) {
204
+ const lines = ["## 최근 학습 (Layer 1 §2 매일 반성)"];
205
+ for (const l of snap.recentLessons) {
206
+ lines.push(`- ${l.time}${l.symbolCode ? " · " + l.symbolCode : ""} · ${l.lesson}`);
207
+ }
208
+ sections.push(lines.join("\n"));
209
+ }
210
+ return sections.join("\n\n");
211
+ }
212
+ /**
213
+ * 사용자 보유/관심 정보 + 최근 학습을 묶어 layer3Header 문자열 반환.
214
+ * Bundle.ts assembleFullPrompt() 의 layer3Header 인자로 전달.
215
+ *
216
+ * @deprecated 새 코드는 collectLayer3Snapshot + formatLayer3Markdown 분리 사용 권장.
217
+ * 이 함수는 두 단계를 한 번에 호출하는 편의 wrapper.
218
+ */
219
+ export async function buildLayer3Header(opts) {
220
+ const snap = await collectLayer3Snapshot(opts);
221
+ return formatLayer3Markdown(snap);
222
+ }
223
+ function fmtPct(n) {
224
+ if (!Number.isFinite(n))
225
+ return "0.00%";
226
+ const sign = n > 0 ? "+" : "";
227
+ return `${sign}${n.toFixed(2)}%`;
228
+ }
229
+ //# sourceMappingURL=context-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-builder.js","sourceRoot":"","sources":["../../../src-server/llm/context-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /** Gemini finishReason → 표준 LlmStopReason 매핑 */
2
+ function mapGeminiStopReason(raw) {
3
+ switch (raw) {
4
+ case "STOP": return "stop";
5
+ case "MAX_TOKENS": return "max_tokens";
6
+ case "SAFETY": return "safety";
7
+ case "RECITATION": return "safety";
8
+ default: return "unknown";
9
+ }
10
+ }
11
+ const BASE = "https://generativelanguage.googleapis.com/v1beta";
12
+ /**
13
+ * Gemini 기본 maxOutputTokens — 응답 잘림 방지 (사용자 정정 · 2026-05-03).
14
+ * Gemini 2.5 Flash/Pro 의 model 한계 (8192) 까지 자유 출력 허용.
15
+ * fetch timeout 없음 (무한대 대기).
16
+ */
17
+ const DEFAULT_MAX_TOKENS = 8192;
18
+ export function createGeminiProvider(opts) {
19
+ return {
20
+ kind: "gemini",
21
+ async test() {
22
+ if (!opts.apiKey)
23
+ return { ok: false, provider: "gemini", error: "apiKey 없음" };
24
+ try {
25
+ // model list · 존재하는지만 확인
26
+ const res = await fetch(`${BASE}/models?key=${encodeURIComponent(opts.apiKey)}`, {
27
+ headers: { accept: "application/json" },
28
+ });
29
+ if (!res.ok) {
30
+ return {
31
+ ok: false,
32
+ provider: "gemini",
33
+ error: `HTTP ${res.status}: ${(await res.text()).slice(0, 120)}`,
34
+ };
35
+ }
36
+ const data = (await res.json());
37
+ const has = data.models?.some((m) => m.name?.includes(opts.model));
38
+ return {
39
+ ok: !!has,
40
+ provider: "gemini",
41
+ model: opts.model,
42
+ detail: has ? "model 확인됨" : "model 미발견 (지원 목록에 없음)",
43
+ };
44
+ }
45
+ catch (e) {
46
+ return { ok: false, provider: "gemini", error: String(e) };
47
+ }
48
+ },
49
+ async complete(c) {
50
+ if (!opts.apiKey)
51
+ throw new Error("Gemini apiKey 없음");
52
+ const url = `${BASE}/models/${encodeURIComponent(opts.model)}:generateContent?key=${encodeURIComponent(opts.apiKey)}`;
53
+ const body = {
54
+ systemInstruction: c.systemPrompt ? { parts: [{ text: c.systemPrompt }] } : undefined,
55
+ contents: [{ role: "user", parts: [{ text: c.userPrompt }] }],
56
+ generationConfig: {
57
+ maxOutputTokens: c.maxTokens ?? DEFAULT_MAX_TOKENS,
58
+ temperature: c.temperature ?? 0.2,
59
+ },
60
+ };
61
+ const res = await fetch(url, {
62
+ method: "POST",
63
+ headers: { "content-type": "application/json" },
64
+ body: JSON.stringify(body),
65
+ });
66
+ if (!res.ok)
67
+ throw new Error(`Gemini HTTP ${res.status}: ${await res.text()}`);
68
+ const data = (await res.json());
69
+ const text = data.candidates?.[0]?.content?.parts?.map((p) => p.text ?? "").join("") ?? "";
70
+ return {
71
+ text,
72
+ model: opts.model,
73
+ provider: "gemini",
74
+ stopReason: mapGeminiStopReason(data.candidates?.[0]?.finishReason),
75
+ usage: data.usageMetadata
76
+ ? {
77
+ inputTokens: data.usageMetadata.promptTokenCount ?? 0,
78
+ outputTokens: data.usageMetadata.candidatesTokenCount ?? 0,
79
+ }
80
+ : undefined,
81
+ raw: data,
82
+ };
83
+ },
84
+ };
85
+ }
86
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src-server/llm/gemini.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export { createGeminiProvider } from "./gemini.js";
2
+ export { createOpenAIProvider } from "./openai.js";
3
+ export { createAnthropicProvider } from "./anthropic.js";
4
+ export { createClaudeCliProvider } from "./claude-cli.js";
5
+ import { createGeminiProvider } from "./gemini.js";
6
+ import { createOpenAIProvider } from "./openai.js";
7
+ import { createAnthropicProvider } from "./anthropic.js";
8
+ import { createClaudeCliProvider } from "./claude-cli.js";
9
+ export function createLlmProvider(cfg) {
10
+ switch (cfg.llm.provider) {
11
+ case "gemini":
12
+ return createGeminiProvider({
13
+ apiKey: cfg.llm.apiKey ?? "",
14
+ model: cfg.llm.model ?? "gemini-2.5-flash",
15
+ });
16
+ case "openai":
17
+ return createOpenAIProvider({
18
+ apiKey: cfg.llm.apiKey ?? "",
19
+ model: cfg.llm.model ?? "gpt-4o-mini",
20
+ });
21
+ case "anthropic":
22
+ return createAnthropicProvider({
23
+ apiKey: cfg.llm.apiKey ?? "",
24
+ model: cfg.llm.model ?? "claude-haiku-3-5",
25
+ });
26
+ case "claude-cli":
27
+ return createClaudeCliProvider({
28
+ binaryPath: cfg.llm.claudeCli?.binaryPath,
29
+ model: cfg.llm.claudeCli?.model ?? "sonnet",
30
+ });
31
+ case "none":
32
+ default:
33
+ return null;
34
+ }
35
+ }
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src-server/llm/index.ts"],"names":[],"mappings":"AAoDA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,UAAU,iBAAiB,CAAC,GAAiB;IACjD,QAAQ,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,oBAAoB,CAAC;gBAC1B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE;gBAC5B,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,kBAAkB;aAC3C,CAAC,CAAC;QACL,KAAK,QAAQ;YACX,OAAO,oBAAoB,CAAC;gBAC1B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE;gBAC5B,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,aAAa;aACtC,CAAC,CAAC;QACL,KAAK,WAAW;YACd,OAAO,uBAAuB,CAAC;gBAC7B,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE;gBAC5B,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,kBAAkB;aAC3C,CAAC,CAAC;QACL,KAAK,YAAY;YACf,OAAO,uBAAuB,CAAC;gBAC7B,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU;gBACzC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,QAAQ;aAC5C,CAAC,CAAC;QACL,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}