@dotobokuri/fleet-console 1.64.0 → 1.66.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.
- package/dist/cli.mjs +26 -22
- package/dist/client/assets/{_baseUniq-DurhRkUz.js → _baseUniq-rDf4uMQX.js} +1 -1
- package/dist/client/assets/{arc-CRs5BdYr.js → arc-btPQ2GHn.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-Djo8uCUV.js → architectureDiagram-Q4EWVU46-DG6KDx34.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-hQdc3yPb.js → blockDiagram-DXYQGD6D-XUrLsQey.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-Czv6wUeb.js → c4Diagram-AHTNJAMY-DuXkZ8b1.js} +1 -1
- package/dist/client/assets/channel-CXR6clX_.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-DXjqdOUQ.js → chunk-4BX2VUAB-C2tTKvHv.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-vvWT5R7G.js → chunk-4TB4RGXK-C5bwM8_h.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DMDBDn4n.js → chunk-55IACEB6-BhcOy6C-.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-CvZM4UpD.js → chunk-EDXVE4YY-TOZwStuB.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-BArng_V9.js → chunk-FMBD7UC4-B8JSJHVV.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-DwNWyoK7.js → chunk-OYMX7WX6-BsNJ9iub.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN--guvcrYz.js → chunk-QZHKN3VN-BhHSM1D6.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-BqxZQZyX.js → chunk-YZCP3GAM-B9d83zwz.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-4x7ZfFx0.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-4x7ZfFx0.js +1 -0
- package/dist/client/assets/clone-lkppJrH0.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-BMg_LOnu.js → cose-bilkent-S5V4N54A-D5mwO2NV.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-Dr7w5bQR.js → dagre-KV5264BT-5fSh4g2E.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-B3mTbXqP.js → diagram-5BDNPKRD-CtCGKgkm.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-qb3u5_YF.js → diagram-G4DWMVQ6-CmGVsepF.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-CBBgto41.js → diagram-MMDJMWI5-BR9Rfnad.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-Cmo3cjOQ.js → diagram-TYMM5635-C9kuBFny.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-HeqZPhtI.js → erDiagram-SMLLAGMA-BlL5tH_h.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-C34ZouQN.js → flowDiagram-DWJPFMVM-IUe6EFlH.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BL2_YoJe.js → ganttDiagram-T4ZO3ILL-G-CTHnXi.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-DSC8Gr0E.js → gitGraphDiagram-UUTBAWPF-COUsDQ0n.js} +1 -1
- package/dist/client/assets/{graph-C4jsVwYI.js → graph-BCiainCT.js} +1 -1
- package/dist/client/assets/index-B1tQI7A5.js +465 -0
- package/dist/client/assets/index-D3b63Dhe.css +1 -0
- package/dist/client/assets/{infoDiagram-42DDH7IO-BX_lYqHx.js → infoDiagram-42DDH7IO-DbNkXGyd.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CsXWVwyY.js → ishikawaDiagram-UXIWVN3A-Iqt-Zs6v.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-ETPWVMNg.js → journeyDiagram-VCZTEJTY-m7TrTD61.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-m7hLIKgZ.js → kanban-definition-6JOO6SKY-Df5KWqsi.js} +1 -1
- package/dist/client/assets/{layout-DrRXjJzL.js → layout-BtA7fX7y.js} +1 -1
- package/dist/client/assets/{linear-DzDd2m9j.js → linear-DVL8mywl.js} +1 -1
- package/dist/client/assets/{mermaid.core-BHkit2JY.js → mermaid.core-CmjUZw2x.js} +4 -4
- package/dist/client/assets/{min-DtwEer1D.js → min-BTu70auM.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-BO-uheb7.js → mindmap-definition-QFDTVHPH-BYpo-Mnc.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B_4VqNKt.js → pieDiagram-DEJITSTG-B8zFmcim.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-HhtqXdkD.js → quadrantDiagram-34T5L4WZ-CMYVBi7F.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-CSotIpLH.js → requirementDiagram-MS252O5E-BFeVMKvJ.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-a8krBcEy.js → sankeyDiagram-XADWPNL6-D2I70l9E.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-D9Tlp8oT.js → sequenceDiagram-FGHM5R23-zawVvGJJ.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-CbEP_Jmm.js → stateDiagram-FHFEXIEX-DnBtIbuv.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-D7rH7_-p.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-CxAJtY22.js → timeline-definition-GMOUNBTQ-0gfoVpmY.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-BSTXi411.js → vennDiagram-DHZGUBPP-CuaEOGH2.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-BipCMOcx.js → wardley-RL74JXVD-C-H0Svof.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-BudrJ8a1.js → wardleyDiagram-NUSXRM2D-MQjjZFwh.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-BYlMZf2g.js → xychartDiagram-5P7HB3ND-BhTAVqtf.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/ledger/routes.mjs +19 -19
- package/dist/fleet-plugins/quota/routes.mjs +19 -19
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +19 -19
- package/dist/fleet-plugins/terminal/routes.mjs +233 -57
- package/dist/fleet.mjs +26 -22
- package/package.json +1 -1
- package/dist/client/assets/channel-DluRfcgW.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-CwNh44Lk.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-CwNh44Lk.js +0 -1
- package/dist/client/assets/clone-ClWdaAWG.js +0 -1
- package/dist/client/assets/index-BuMY4qU-.js +0 -465
- package/dist/client/assets/index-DxjgOu3C.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-B9iCjiGH.js +0 -1
|
@@ -20229,6 +20229,22 @@ function projectClaudeContextInputTokens(inputTokens, advertisedContextWindow, u
|
|
|
20229
20229
|
Math.ceil(inputTokens * claudeCompactThreshold / providerCompactThreshold)
|
|
20230
20230
|
);
|
|
20231
20231
|
}
|
|
20232
|
+
function unprojectClaudeContextInputTokens(projectedTokens, advertisedContextWindow, claudeCoordinate, compactCeiling) {
|
|
20233
|
+
if (!Number.isFinite(projectedTokens) || projectedTokens < 0) return projectedTokens;
|
|
20234
|
+
const advertisedWindow = positiveContextWindow(advertisedContextWindow);
|
|
20235
|
+
if (advertisedWindow === void 0) return projectedTokens;
|
|
20236
|
+
if (claudeCoordinate !== CLAUDE_DEFAULT_CONTEXT_WINDOW && claudeCoordinate !== CLAUDE_COMPAT_CONTEXT_WINDOW) {
|
|
20237
|
+
return projectedTokens;
|
|
20238
|
+
}
|
|
20239
|
+
const claudeCompactThreshold = claudeCoordinate - CLAUDE_COMPACT_RESERVE;
|
|
20240
|
+
if (claudeCompactThreshold <= 0) return projectedTokens;
|
|
20241
|
+
const providerCompactThreshold = compactThresholdTokens(advertisedWindow, compactCeiling);
|
|
20242
|
+
if (providerCompactThreshold <= 0) return projectedTokens;
|
|
20243
|
+
return Math.min(
|
|
20244
|
+
advertisedWindow,
|
|
20245
|
+
Math.round(projectedTokens * providerCompactThreshold / claudeCompactThreshold)
|
|
20246
|
+
);
|
|
20247
|
+
}
|
|
20232
20248
|
function compactThresholdTokens(window, compactCeiling) {
|
|
20233
20249
|
if (!Number.isFinite(window) || window <= 0) return window;
|
|
20234
20250
|
const percent2 = compactCeilingPercent(compactCeiling);
|
|
@@ -20839,7 +20855,7 @@ var models_default = {
|
|
|
20839
20855
|
codex: {
|
|
20840
20856
|
name: "Codex",
|
|
20841
20857
|
defaultModel: "gpt-5.6-sol",
|
|
20842
|
-
source: "codex app-server model/list (codex-cli 0.147.0, observed 2026-08-11) for model/effort/service-tier and the unsuffixed 272000 defaults; Fleet catalog effort ladders are capped at max because harness launch capabilities are not model rungs; 2026-08-17 production Codex live observations added explicit
|
|
20858
|
+
source: "codex app-server model/list (codex-cli 0.147.0, observed 2026-08-11) for model/effort/service-tier and the unsuffixed 272000 defaults; Fleet catalog effort ladders are capped at max because harness launch capabilities are not model rungs; 2026-08-17 production Codex live observations added explicit 524K (524288) and explicit 1M (1000000) variants on the same upstream bases",
|
|
20843
20859
|
models: [
|
|
20844
20860
|
{
|
|
20845
20861
|
modelId: "gpt-5.6-sol",
|
|
@@ -20968,8 +20984,8 @@ var models_default = {
|
|
|
20968
20984
|
benchmarkKey: "gpt-5.6-luna"
|
|
20969
20985
|
},
|
|
20970
20986
|
{
|
|
20971
|
-
modelId: "gpt-5.6-sol-
|
|
20972
|
-
name: "GPT-5.6-Sol-
|
|
20987
|
+
modelId: "gpt-5.6-sol-524k",
|
|
20988
|
+
name: "GPT-5.6-Sol-524K",
|
|
20973
20989
|
capabilityClass: "flagship",
|
|
20974
20990
|
providerModelId: "gpt-5.6-sol",
|
|
20975
20991
|
contextWindow: 524288,
|
|
@@ -20984,13 +21000,13 @@ var models_default = {
|
|
|
20984
21000
|
]
|
|
20985
21001
|
},
|
|
20986
21002
|
aliases: [
|
|
20987
|
-
"gpt-5.6-sol-
|
|
21003
|
+
"gpt-5.6-sol-524k"
|
|
20988
21004
|
],
|
|
20989
21005
|
benchmarkKey: "gpt-5.6-sol"
|
|
20990
21006
|
},
|
|
20991
21007
|
{
|
|
20992
|
-
modelId: "gpt-5.6-sol-
|
|
20993
|
-
name: "GPT-5.6-Sol-
|
|
21008
|
+
modelId: "gpt-5.6-sol-524k-fast",
|
|
21009
|
+
name: "GPT-5.6-Sol-524K-Fast",
|
|
20994
21010
|
capabilityClass: "flagship",
|
|
20995
21011
|
providerModelId: "gpt-5.6-sol",
|
|
20996
21012
|
serviceTier: "priority",
|
|
@@ -21006,13 +21022,13 @@ var models_default = {
|
|
|
21006
21022
|
]
|
|
21007
21023
|
},
|
|
21008
21024
|
aliases: [
|
|
21009
|
-
"gpt-5.6-sol-
|
|
21025
|
+
"gpt-5.6-sol-524k-fast"
|
|
21010
21026
|
],
|
|
21011
21027
|
benchmarkKey: "gpt-5.6-sol"
|
|
21012
21028
|
},
|
|
21013
21029
|
{
|
|
21014
|
-
modelId: "gpt-5.6-luna-
|
|
21015
|
-
name: "GPT-5.6-Luna-
|
|
21030
|
+
modelId: "gpt-5.6-luna-524k",
|
|
21031
|
+
name: "GPT-5.6-Luna-524K",
|
|
21016
21032
|
capabilityClass: "light",
|
|
21017
21033
|
providerModelId: "gpt-5.6-luna",
|
|
21018
21034
|
contextWindow: 524288,
|
|
@@ -21027,13 +21043,13 @@ var models_default = {
|
|
|
21027
21043
|
]
|
|
21028
21044
|
},
|
|
21029
21045
|
aliases: [
|
|
21030
|
-
"gpt-5.6-luna-
|
|
21046
|
+
"gpt-5.6-luna-524k"
|
|
21031
21047
|
],
|
|
21032
21048
|
benchmarkKey: "gpt-5.6-luna"
|
|
21033
21049
|
},
|
|
21034
21050
|
{
|
|
21035
|
-
modelId: "gpt-5.6-luna-
|
|
21036
|
-
name: "GPT-5.6-Luna-
|
|
21051
|
+
modelId: "gpt-5.6-luna-524k-fast",
|
|
21052
|
+
name: "GPT-5.6-Luna-524K-Fast",
|
|
21037
21053
|
capabilityClass: "light",
|
|
21038
21054
|
providerModelId: "gpt-5.6-luna",
|
|
21039
21055
|
serviceTier: "priority",
|
|
@@ -21049,13 +21065,13 @@ var models_default = {
|
|
|
21049
21065
|
]
|
|
21050
21066
|
},
|
|
21051
21067
|
aliases: [
|
|
21052
|
-
"gpt-5.6-luna-
|
|
21068
|
+
"gpt-5.6-luna-524k-fast"
|
|
21053
21069
|
],
|
|
21054
21070
|
benchmarkKey: "gpt-5.6-luna"
|
|
21055
21071
|
},
|
|
21056
21072
|
{
|
|
21057
|
-
modelId: "gpt-5.6-terra-
|
|
21058
|
-
name: "GPT-5.6-Terra-
|
|
21073
|
+
modelId: "gpt-5.6-terra-524k",
|
|
21074
|
+
name: "GPT-5.6-Terra-524K",
|
|
21059
21075
|
capabilityClass: "standard",
|
|
21060
21076
|
providerModelId: "gpt-5.6-terra",
|
|
21061
21077
|
contextWindow: 524288,
|
|
@@ -21070,13 +21086,13 @@ var models_default = {
|
|
|
21070
21086
|
]
|
|
21071
21087
|
},
|
|
21072
21088
|
aliases: [
|
|
21073
|
-
"gpt-5.6-terra-
|
|
21089
|
+
"gpt-5.6-terra-524k"
|
|
21074
21090
|
],
|
|
21075
21091
|
benchmarkKey: "gpt-5.6-terra"
|
|
21076
21092
|
},
|
|
21077
21093
|
{
|
|
21078
|
-
modelId: "gpt-5.6-terra-
|
|
21079
|
-
name: "GPT-5.6-Terra-
|
|
21094
|
+
modelId: "gpt-5.6-terra-524k-fast",
|
|
21095
|
+
name: "GPT-5.6-Terra-524K-Fast",
|
|
21080
21096
|
capabilityClass: "standard",
|
|
21081
21097
|
providerModelId: "gpt-5.6-terra",
|
|
21082
21098
|
serviceTier: "priority",
|
|
@@ -21092,7 +21108,7 @@ var models_default = {
|
|
|
21092
21108
|
]
|
|
21093
21109
|
},
|
|
21094
21110
|
aliases: [
|
|
21095
|
-
"gpt-5.6-terra-
|
|
21111
|
+
"gpt-5.6-terra-524k-fast"
|
|
21096
21112
|
],
|
|
21097
21113
|
benchmarkKey: "gpt-5.6-terra"
|
|
21098
21114
|
},
|
|
@@ -48605,6 +48621,18 @@ var AgentChatSession = class {
|
|
|
48605
48621
|
* 답은 턴이 끝난 뒤에 오므로(실측), 그 사이 새 턴이 시작했다면 그 값은 남의 턴 자리에 앉는다.
|
|
48606
48622
|
*/
|
|
48607
48623
|
contextGeneration = 0;
|
|
48624
|
+
/**
|
|
48625
|
+
* control 요청이 하나 떠 있는가.
|
|
48626
|
+
*
|
|
48627
|
+
* 겹쳐 던지면 자식이 직렬로 처리한다 — 실측하면 요청 하나에 약 30초가 들고, 셋을 던진 마지막
|
|
48628
|
+
* 답은 100초 뒤에 왔다. 그래서 앞선 요청이 살아 있는 동안에는 새로 던지지 않는다. 놓친 창은
|
|
48629
|
+
* 다음 경계(턴 시작·턴 종료)가 다시 얻는다.
|
|
48630
|
+
*/
|
|
48631
|
+
contextInFlight = false;
|
|
48632
|
+
/** 턴이 도는 동안 흘러간 라이브 총량. 턴 경계에서 비운다. */
|
|
48633
|
+
liveContextTotal = null;
|
|
48634
|
+
/** 자식이 스냅숏에서 직접 말한 좌표. 도착하기 전에는 모델 id에서 유도한다. */
|
|
48635
|
+
observedClaudeCoordinate = null;
|
|
48608
48636
|
constructor(operationId, seed, createSdk) {
|
|
48609
48637
|
this.operationId = operationId;
|
|
48610
48638
|
this.seed = seed;
|
|
@@ -48941,25 +48969,33 @@ var AgentChatSession = class {
|
|
|
48941
48969
|
});
|
|
48942
48970
|
}
|
|
48943
48971
|
/**
|
|
48944
|
-
*
|
|
48972
|
+
* 자식에게 문맥 **내역**을 묻고, 답이 오면 저널에 싣는다. 두 경계에서 불린다 — 턴을 보내기
|
|
48973
|
+
* 직전(`"start"`)과 턴이 닫힌 직후(`"end"`).
|
|
48945
48974
|
*
|
|
48946
|
-
*
|
|
48947
|
-
*
|
|
48948
|
-
*
|
|
48975
|
+
* 왕복이 느리다는 것이 이 배선의 전제다(실측 21~88초, 요청 하나에 약 30초, 직렬 큐). 그래서
|
|
48976
|
+
* 총량은 이 채널에 맡기지 않고 `message_delta` usage가 진다. 여기서 얻는 것은 카테고리 분해 —
|
|
48977
|
+
* 그것만은 control 채널이 유일한 출처다.
|
|
48949
48978
|
*
|
|
48950
|
-
*
|
|
48951
|
-
*
|
|
48979
|
+
* 턴 중에는 아예 묻지 않는다. 자식이 턴이 시작되면 control을 닫아 +0ms의 요청만 답을 받고
|
|
48980
|
+
* 그 뒤는 전부 "Query closed before response received"로 끝난다(실측). 유휴 폴링도 하지 않는다 —
|
|
48981
|
+
* 답은 오지만 요청마다 30초를 태우고 큐만 밀린다.
|
|
48952
48982
|
*
|
|
48953
48983
|
* 응답을 기다리지 않는 이유는 스트림 때문이다: 여기서 await하면 첫 메시지 소비가 그만큼 늦다.
|
|
48954
|
-
* 늦게 도착한 답도 같은 턴의 시작 시점 값이므로, 그때 실어도 뜻이 달라지지 않는다.
|
|
48955
48984
|
*/
|
|
48956
|
-
|
|
48985
|
+
requestContextSnapshot(session, asOf) {
|
|
48986
|
+
if (this.contextInFlight) return;
|
|
48957
48987
|
const generation = ++this.contextGeneration;
|
|
48988
|
+
this.contextInFlight = true;
|
|
48989
|
+
const settle = (usage4) => {
|
|
48990
|
+
this.contextInFlight = false;
|
|
48991
|
+
if (usage4 && generation === this.contextGeneration) this.pushContext(usage4, asOf);
|
|
48992
|
+
};
|
|
48958
48993
|
try {
|
|
48959
|
-
void session.getContextUsage().then((
|
|
48960
|
-
|
|
48961
|
-
}
|
|
48994
|
+
void session.getContextUsage().then(settle, () => {
|
|
48995
|
+
this.contextInFlight = false;
|
|
48996
|
+
});
|
|
48962
48997
|
} catch {
|
|
48998
|
+
this.contextInFlight = false;
|
|
48963
48999
|
}
|
|
48964
49000
|
}
|
|
48965
49001
|
/**
|
|
@@ -48973,25 +49009,100 @@ var AgentChatSession = class {
|
|
|
48973
49009
|
* 예약분(자동 압축 여유)과 남은 자리는 **쓴 것이 아니다**. 같은 목록에 두면 합이 언제나 창
|
|
48974
49010
|
* 전체가 되어 미터가 항상 100%를 가리킨다.
|
|
48975
49011
|
*/
|
|
48976
|
-
pushContext(usage4) {
|
|
49012
|
+
pushContext(usage4, asOf) {
|
|
49013
|
+
this.observedClaudeCoordinate = usage4.max;
|
|
48977
49014
|
const spent = usage4.categories.filter((category) => !category.deferred && category.tokens > 0 && !CONTEXT_UNSPENT.has(category.name));
|
|
48978
49015
|
const reserved = usage4.categories.find((category) => category.name === CONTEXT_RESERVED_NAME);
|
|
49016
|
+
const window = this.realWindow(usage4.max);
|
|
49017
|
+
const slices = spent.map((category) => ({
|
|
49018
|
+
name: category.name,
|
|
49019
|
+
tokens: window ? window.unproject(category.tokens) : category.tokens
|
|
49020
|
+
}));
|
|
48979
49021
|
this.push({
|
|
48980
49022
|
kind: "context",
|
|
48981
|
-
|
|
48982
|
-
|
|
48983
|
-
|
|
48984
|
-
|
|
48985
|
-
|
|
48986
|
-
...
|
|
49023
|
+
asOf,
|
|
49024
|
+
total: slices.reduce((sum, slice) => sum + slice.tokens, 0),
|
|
49025
|
+
max: window ? window.max : usage4.max,
|
|
49026
|
+
// 예약분은 되돌리지 않고 **갈아 끼운다**. 자식의 값은 자기 좌표의 여유(max − compactAt)이고
|
|
49027
|
+
// 실제 여유는 정책이 정하는 다른 수다 — 같은 비율로 늘리면 있지도 않은 자리를 예약해 둔다.
|
|
49028
|
+
...window ? window.max > window.compactAt ? { reserved: window.max - window.compactAt } : {} : reserved && reserved.tokens > 0 ? { reserved: reserved.tokens } : {},
|
|
49029
|
+
...window ? usage4.compactAt === null ? {} : { compactAt: window.compactAt } : usage4.compactAt === null ? {} : { compactAt: usage4.compactAt },
|
|
49030
|
+
slices,
|
|
49031
|
+
...usage4.memoryFiles.length > 0 ? {
|
|
49032
|
+
memoryFiles: usage4.memoryFiles.map((file2) => ({
|
|
49033
|
+
name: file2.path,
|
|
49034
|
+
tokens: window ? window.unproject(file2.tokens) : file2.tokens
|
|
49035
|
+
}))
|
|
49036
|
+
} : {},
|
|
48987
49037
|
...usage4.mcpTools.length > 0 ? {
|
|
48988
49038
|
mcpTools: usage4.mcpTools.map((tool) => ({
|
|
48989
49039
|
name: tool.server ? `${tool.server} \xB7 ${tool.name}` : tool.name,
|
|
48990
|
-
tokens: tool.tokens
|
|
49040
|
+
tokens: window ? window.unproject(tool.tokens) : tool.tokens
|
|
48991
49041
|
}))
|
|
48992
49042
|
} : {}
|
|
48993
49043
|
});
|
|
48994
49044
|
}
|
|
49045
|
+
/**
|
|
49046
|
+
* 턴이 도는 동안 총량을 흘린다. 미터가 이 턴을 따라 움직이는 유일한 경로다.
|
|
49047
|
+
*
|
|
49048
|
+
* 읽는 것은 `message_delta`의 usage **하나뿐**이며, 그것은 소거로 남은 결과다(실측):
|
|
49049
|
+
* `message_start`와 완성 `assistant`의 usage는 언제나 0으로 오고, `result.usage`는 그 턴의 모든
|
|
49050
|
+
* 모델 호출을 **합산한** 값이어서 창 점유가 아니다 — 도구를 다섯 번 돈 턴에서 61,630이었고 같은
|
|
49051
|
+
* 순간의 실제 점유는 15,785였다. 그것을 총량으로 쓰면 미터가 네 배로 뛴다.
|
|
49052
|
+
*
|
|
49053
|
+
* 서브에이전트의 usage도 제외한다. 그 창은 부모의 창이 아니다.
|
|
49054
|
+
*/
|
|
49055
|
+
trackLiveContext(message) {
|
|
49056
|
+
if (message.type !== "stream_event") return;
|
|
49057
|
+
if (typeof message.parent_tool_use_id === "string" && message.parent_tool_use_id.length > 0) return;
|
|
49058
|
+
const event = message.event;
|
|
49059
|
+
if (!isRecord14(event) || event.type !== "message_delta") return;
|
|
49060
|
+
const total = readClaudeOccupiedInputTokens(event.usage);
|
|
49061
|
+
if (total === null) return;
|
|
49062
|
+
const claudeCoordinate = this.claudeCoordinate();
|
|
49063
|
+
const window = this.realWindow(claudeCoordinate);
|
|
49064
|
+
const live = window ? window.unproject(total) : total;
|
|
49065
|
+
if (this.liveContextTotal === live) return;
|
|
49066
|
+
this.liveContextTotal = live;
|
|
49067
|
+
this.pushEphemeral({
|
|
49068
|
+
kind: "context-live",
|
|
49069
|
+
total: live,
|
|
49070
|
+
max: window ? window.max : claudeCoordinate
|
|
49071
|
+
});
|
|
49072
|
+
}
|
|
49073
|
+
/**
|
|
49074
|
+
* 자식이 이 세션을 재는 좌표.
|
|
49075
|
+
*
|
|
49076
|
+
* 스냅숏이 한 번이라도 왔으면 자식이 직접 말한 값이 권위다. 그 전에는 유도한다 — 좌표를 정하는
|
|
49077
|
+
* 것은 모델 id의 `[1m]` 마커이고, 그 마커를 붙이는 규칙이 곧 카탈로그 창이 1M에 닿는지 여부다.
|
|
49078
|
+
* 유도가 필요한 이유는 라이브 총량이 첫 스냅숏(왕복 30초)을 기다릴 수 없기 때문이다.
|
|
49079
|
+
*/
|
|
49080
|
+
claudeCoordinate() {
|
|
49081
|
+
if (this.observedClaudeCoordinate !== null) return this.observedClaudeCoordinate;
|
|
49082
|
+
const window = this.seed.contextWindow;
|
|
49083
|
+
const oneMillion = typeof window === "number" && Number.isFinite(window) && window > 0 ? window >= CLAUDE_COMPAT_CONTEXT_WINDOW : hasClaudeOneMillionMarker(this.seed.model);
|
|
49084
|
+
return oneMillion ? CLAUDE_COMPAT_CONTEXT_WINDOW : CLAUDE_DEFAULT_CONTEXT_WINDOW;
|
|
49085
|
+
}
|
|
49086
|
+
/**
|
|
49087
|
+
* 자식이 보고한 좌표를 이 모델의 실제 창으로 되돌리는 자.
|
|
49088
|
+
*
|
|
49089
|
+
* `null`은 되돌릴 것이 없다는 뜻이며 세 경우가 여기로 온다: 시드에 카탈로그 창이 없는 세션
|
|
49090
|
+
* (네이티브 Claude 모델·카탈로그 밖 id), 그리고 자식이 자기 두 좌표가 아닌 값을 말한 세션 —
|
|
49091
|
+
* 후자는 역함수가 스스로 항등으로 접는다. 어느 경우든 오늘의 숫자가 그대로 나간다.
|
|
49092
|
+
*/
|
|
49093
|
+
realWindow(claudeCoordinate) {
|
|
49094
|
+
const max = this.seed.contextWindow;
|
|
49095
|
+
if (typeof max !== "number" || !Number.isFinite(max) || max <= 0) return null;
|
|
49096
|
+
if (claudeCoordinate !== CLAUDE_DEFAULT_CONTEXT_WINDOW && claudeCoordinate !== CLAUDE_COMPAT_CONTEXT_WINDOW) {
|
|
49097
|
+
return null;
|
|
49098
|
+
}
|
|
49099
|
+
const ceiling = this.seed.compactCeiling ?? null;
|
|
49100
|
+
return {
|
|
49101
|
+
max,
|
|
49102
|
+
compactAt: compactThresholdTokens(max, ceiling),
|
|
49103
|
+
unproject: (tokens) => unprojectClaudeContextInputTokens(tokens, max, claudeCoordinate, ceiling)
|
|
49104
|
+
};
|
|
49105
|
+
}
|
|
48995
49106
|
push(event) {
|
|
48996
49107
|
const entry = { seq: ++this.seq, event };
|
|
48997
49108
|
if (event.kind === "job-progress") {
|
|
@@ -49125,6 +49236,7 @@ var AgentChatSession = class {
|
|
|
49125
49236
|
if (this.latestSessionId !== this.reportedSessionId) this.syncProviderSessionOnce();
|
|
49126
49237
|
}
|
|
49127
49238
|
this.rememberJobOutput(message);
|
|
49239
|
+
this.trackLiveContext(message);
|
|
49128
49240
|
for (const event of chatEventsFromSdkMessage(message, { cwd: this.seed.cwd, toolNames: this.toolNames })) {
|
|
49129
49241
|
this.ingest(event);
|
|
49130
49242
|
}
|
|
@@ -49202,10 +49314,13 @@ var AgentChatSession = class {
|
|
|
49202
49314
|
});
|
|
49203
49315
|
this.abandonAsks("The turn ended before the question was answered.");
|
|
49204
49316
|
this.seed.reportActivity(false);
|
|
49317
|
+
this.liveContextTotal = null;
|
|
49205
49318
|
const awaiting = this.awaitingTurn;
|
|
49206
49319
|
this.awaitingTurn = null;
|
|
49207
49320
|
awaiting?.();
|
|
49208
49321
|
this.releaseTurnCloseWaiters();
|
|
49322
|
+
const session = this.session;
|
|
49323
|
+
if (session) this.requestContextSnapshot(session, "end");
|
|
49209
49324
|
}
|
|
49210
49325
|
/** 자리가 비었음을 줄 서 있던 디스패치들에게 알린다. 결말 하나가 전부를 깨운다. */
|
|
49211
49326
|
releaseTurnCloseWaiters() {
|
|
@@ -49279,7 +49394,7 @@ var AgentChatSession = class {
|
|
|
49279
49394
|
const settled = new Promise((resolve3) => {
|
|
49280
49395
|
this.awaitingTurn = resolve3;
|
|
49281
49396
|
});
|
|
49282
|
-
this.
|
|
49397
|
+
this.requestContextSnapshot(session, "start");
|
|
49283
49398
|
session.send(text2);
|
|
49284
49399
|
this.turnReachedChild = true;
|
|
49285
49400
|
await settled;
|
|
@@ -49418,6 +49533,21 @@ var AgentChatRegistry = class {
|
|
|
49418
49533
|
await Promise.all([...operationIds].map((operationId) => this.dispose(operationId)));
|
|
49419
49534
|
}
|
|
49420
49535
|
};
|
|
49536
|
+
function isRecord14(value) {
|
|
49537
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49538
|
+
}
|
|
49539
|
+
function readClaudeOccupiedInputTokens(usage4) {
|
|
49540
|
+
if (!isRecord14(usage4)) return null;
|
|
49541
|
+
let total = 0;
|
|
49542
|
+
let found = false;
|
|
49543
|
+
for (const field of ["input_tokens", "cache_read_input_tokens", "cache_creation_input_tokens"]) {
|
|
49544
|
+
const tokens = usage4[field];
|
|
49545
|
+
if (typeof tokens !== "number" || !Number.isFinite(tokens) || tokens < 0) continue;
|
|
49546
|
+
total += tokens;
|
|
49547
|
+
found = true;
|
|
49548
|
+
}
|
|
49549
|
+
return found ? total : null;
|
|
49550
|
+
}
|
|
49421
49551
|
|
|
49422
49552
|
// ../fleet-plugins/terminal/server/agent-api/chat-ws.ts
|
|
49423
49553
|
var MAX_CHAT_ANSWER_MESSAGE_CHARS = 2e3;
|
|
@@ -49530,6 +49660,15 @@ var ANALYSIS_ERROR_CODES = {
|
|
|
49530
49660
|
var ANALYST_GATEWAY_CLI_ID = "claude-gateway";
|
|
49531
49661
|
var ANALYST_DEFAULT_MODEL = "sonnet";
|
|
49532
49662
|
var ANALYST_DEFAULT_EFFORT = "low";
|
|
49663
|
+
var ANALYST_EFFORT_LEVELS = ["low", "medium", "high"];
|
|
49664
|
+
function clampAnalystEffortLevels(levels) {
|
|
49665
|
+
return ANALYST_EFFORT_LEVELS.filter((level) => levels.includes(level));
|
|
49666
|
+
}
|
|
49667
|
+
function clampAnalystDefaultEffort(levels, fallback) {
|
|
49668
|
+
if (fallback && levels.includes(fallback)) return fallback;
|
|
49669
|
+
if (levels.includes(ANALYST_DEFAULT_EFFORT)) return ANALYST_DEFAULT_EFFORT;
|
|
49670
|
+
return levels[0];
|
|
49671
|
+
}
|
|
49533
49672
|
var NATIVE_CLAUDE_LABELS = {
|
|
49534
49673
|
"fable[1m]": "Claude Fable",
|
|
49535
49674
|
sonnet: "Claude Sonnet",
|
|
@@ -49539,26 +49678,33 @@ function nativeClaudeAnalystModels() {
|
|
|
49539
49678
|
return NATIVE_CLAUDE_MODEL_ALIASES.map((modelId) => ({
|
|
49540
49679
|
modelId,
|
|
49541
49680
|
name: NATIVE_CLAUDE_LABELS[modelId] ?? modelId,
|
|
49542
|
-
effort: { supported: true, levels: [...
|
|
49681
|
+
effort: { supported: true, levels: [...ANALYST_EFFORT_LEVELS] }
|
|
49543
49682
|
}));
|
|
49544
49683
|
}
|
|
49545
49684
|
function resolveAnalysisGatewayBaseUrl(origin) {
|
|
49546
49685
|
return `${origin.replace(/\/+$/u, "")}/plugins/terminal/${AI_GATEWAY_ROUTE_SEGMENT}`;
|
|
49547
49686
|
}
|
|
49548
49687
|
function buildAnalysisCatalog(nativeModels, gatewayModels, available) {
|
|
49549
|
-
const native = nativeModels.map((model) =>
|
|
49550
|
-
|
|
49551
|
-
|
|
49552
|
-
|
|
49553
|
-
|
|
49554
|
-
|
|
49555
|
-
|
|
49556
|
-
|
|
49557
|
-
|
|
49558
|
-
|
|
49559
|
-
|
|
49560
|
-
effortLevels
|
|
49561
|
-
|
|
49688
|
+
const native = nativeModels.map((model) => {
|
|
49689
|
+
const effortLevels = model.effort.supported ? clampAnalystEffortLevels(model.effort.levels ?? []) : [];
|
|
49690
|
+
const defaultEffort = model.modelId === ANALYST_DEFAULT_MODEL ? clampAnalystDefaultEffort(effortLevels, ANALYST_DEFAULT_EFFORT) : model.effort.supported ? clampAnalystDefaultEffort(effortLevels, model.effort.default) : void 0;
|
|
49691
|
+
return {
|
|
49692
|
+
id: model.modelId,
|
|
49693
|
+
label: model.name,
|
|
49694
|
+
effortLevels,
|
|
49695
|
+
...defaultEffort ? { defaultEffort } : {}
|
|
49696
|
+
};
|
|
49697
|
+
});
|
|
49698
|
+
const gateway = gatewayModels.map((model) => {
|
|
49699
|
+
const effortLevels = model.effort.supported ? clampAnalystEffortLevels(model.effort.levels) : [];
|
|
49700
|
+
return {
|
|
49701
|
+
id: toClaudeGatewayModelId(model),
|
|
49702
|
+
label: model.displayName,
|
|
49703
|
+
// 게이트웨이 모델 스키마에는 기본 강도가 없다. 없는 값을 지어내면 사용자가 고르지 않은
|
|
49704
|
+
// 강도로 돈다. 클램프 후 단이 비면 강도 없는 모델과 같다.
|
|
49705
|
+
effortLevels
|
|
49706
|
+
};
|
|
49707
|
+
});
|
|
49562
49708
|
const models = [...native, ...gateway];
|
|
49563
49709
|
return {
|
|
49564
49710
|
clis: [{
|
|
@@ -49575,7 +49721,7 @@ function analysisError(code, message) {
|
|
|
49575
49721
|
return { error: { code, message } };
|
|
49576
49722
|
}
|
|
49577
49723
|
function isAnalysisSelection(catalog, value) {
|
|
49578
|
-
if (!
|
|
49724
|
+
if (!isRecord15(value) || !hasExactKeys(value, ["cliId", "model", "effort", "language"]) || typeof value.cliId !== "string" || typeof value.model !== "string" || value.effort !== void 0 && typeof value.effort !== "string" || value.language !== void 0 && value.language !== "en" && value.language !== "ko") return false;
|
|
49579
49725
|
const cli = catalog.clis.find((candidate) => candidate.cliId === value.cliId);
|
|
49580
49726
|
if (!cli?.available) return false;
|
|
49581
49727
|
const model = cli.models.find((candidate) => candidate.id === value.model);
|
|
@@ -49584,9 +49730,9 @@ function isAnalysisSelection(catalog, value) {
|
|
|
49584
49730
|
return typeof value.effort === "string" && value.effort.length > 0 && model.effortLevels.includes(value.effort);
|
|
49585
49731
|
}
|
|
49586
49732
|
function isMessageBody(value) {
|
|
49587
|
-
return
|
|
49733
|
+
return isRecord15(value) && hasExactKeys(value, ["text"]) && typeof value.text === "string" && value.text.trim().length > 0;
|
|
49588
49734
|
}
|
|
49589
|
-
function
|
|
49735
|
+
function isRecord15(value) {
|
|
49590
49736
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49591
49737
|
}
|
|
49592
49738
|
function hasExactKeys(value, keys) {
|
|
@@ -50153,6 +50299,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50153
50299
|
}
|
|
50154
50300
|
const launchOptions = readLaunchOptions(body, cliId, res);
|
|
50155
50301
|
if (launchOptions === false) return true;
|
|
50302
|
+
const geometry = readOptionalGeometry(body?.geometry, res);
|
|
50303
|
+
if (geometry === false) return true;
|
|
50156
50304
|
if (body?.prompt !== void 0 && typeof body.prompt !== "string") {
|
|
50157
50305
|
ctx.host.http.writeJson(res, 400, { error: "invalid_prompt" });
|
|
50158
50306
|
return true;
|
|
@@ -50193,7 +50341,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50193
50341
|
...launchOptions,
|
|
50194
50342
|
...composedPrompt ? { prompt: composedPrompt } : {},
|
|
50195
50343
|
...attachmentIds.length > 0 ? { attachmentIds } : {},
|
|
50196
|
-
...chatBorn ? { chatBorn: true } : {}
|
|
50344
|
+
...chatBorn ? { chatBorn: true } : {},
|
|
50345
|
+
...geometry ? { geometry } : {}
|
|
50197
50346
|
});
|
|
50198
50347
|
} catch (error51) {
|
|
50199
50348
|
if (attachmentIds.length > 0) launchAttachments.unreserve(attachmentIds);
|
|
@@ -50209,6 +50358,24 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50209
50358
|
}
|
|
50210
50359
|
return value;
|
|
50211
50360
|
}
|
|
50361
|
+
function readOptionalGeometry(value, res) {
|
|
50362
|
+
if (value === void 0) return void 0;
|
|
50363
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
50364
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_geometry" });
|
|
50365
|
+
return false;
|
|
50366
|
+
}
|
|
50367
|
+
const candidate = value;
|
|
50368
|
+
const x = candidate.x;
|
|
50369
|
+
const y = candidate.y;
|
|
50370
|
+
const width = candidate.width;
|
|
50371
|
+
const height = candidate.height;
|
|
50372
|
+
const zIndex = candidate.zIndex;
|
|
50373
|
+
if (typeof x !== "number" || !Number.isFinite(x) || typeof y !== "number" || !Number.isFinite(y) || typeof width !== "number" || !Number.isFinite(width) || typeof height !== "number" || !Number.isFinite(height) || typeof zIndex !== "number" || !Number.isFinite(zIndex)) {
|
|
50374
|
+
ctx.host.http.writeJson(res, 400, { error: "invalid_geometry" });
|
|
50375
|
+
return false;
|
|
50376
|
+
}
|
|
50377
|
+
return { x, y, width, height, zIndex };
|
|
50378
|
+
}
|
|
50212
50379
|
function readLaunchOptions(body, cliId, res) {
|
|
50213
50380
|
if (body?.model !== void 0 && typeof body.model !== "string" || body?.effort !== void 0 && typeof body.effort !== "string") {
|
|
50214
50381
|
ctx.host.http.writeJson(res, 400, { error: "invalid_launch_option" });
|
|
@@ -50333,6 +50500,7 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50333
50500
|
// "transcript 부재는 상실이 아니라 아직 첫 턴 전"이라는 뜻을 durable하게 남긴다.
|
|
50334
50501
|
...launchOptions.chatBorn ? { [CHAT_MODE_PAYLOAD_KEY]: true, [CHAT_BORN_PAYLOAD_KEY]: true } : {}
|
|
50335
50502
|
},
|
|
50503
|
+
...launchOptions.geometry ? { geometry: launchOptions.geometry } : {},
|
|
50336
50504
|
createdAt: session.createdAt
|
|
50337
50505
|
});
|
|
50338
50506
|
if (launchOptions.chatBorn) {
|
|
@@ -50813,6 +50981,9 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50813
50981
|
});
|
|
50814
50982
|
} catch {
|
|
50815
50983
|
}
|
|
50984
|
+
const gatewayModel = findGatewayModel(model);
|
|
50985
|
+
const gatewayContextWindow = typeof gatewayModel?.contextWindow === "number" && Number.isFinite(gatewayModel.contextWindow) && gatewayModel.contextWindow > 0 ? gatewayModel.contextWindow : void 0;
|
|
50986
|
+
const gatewayCompactCeiling = gatewayContextWindow === void 0 ? void 0 : deps.readAiGatewaySettings?.().compactCeiling ?? null;
|
|
50816
50987
|
const chatSkillOverrides = buildDisabledSkillOverrides(GATEWAY_DISABLED_CLAUDE_SKILLS);
|
|
50817
50988
|
const systemPromptMode = deps.globalOptionsService.load().claudeGatewaySystemPromptMode ?? "append";
|
|
50818
50989
|
const systemPrompt = systemPromptMode === "off" ? void 0 : { mode: systemPromptMode, text: createSystemPromptBuilder().build() };
|
|
@@ -50822,6 +50993,11 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50822
50993
|
seed: {
|
|
50823
50994
|
baseUrl: gatewayBaseUrl,
|
|
50824
50995
|
model,
|
|
50996
|
+
// 자식은 창이 500k인 모델도 자기 200k 좌표로 재고, 그 좌표를 물어보는 모든 표면에 그대로
|
|
50997
|
+
// 말한다. 실제 창과 투영에 쓰인 압축 정책을 함께 실어야 세션이 그것을 되돌릴 수 있다.
|
|
50998
|
+
// 네이티브 Claude 모델은 카탈로그에 없으므로 두 값 없이 지나가고 오늘의 숫자를 유지한다.
|
|
50999
|
+
...gatewayContextWindow === void 0 ? {} : { contextWindow: gatewayContextWindow },
|
|
51000
|
+
...gatewayCompactCeiling === void 0 ? {} : { compactCeiling: gatewayCompactCeiling },
|
|
50825
51001
|
...launchEffort ? { effort: launchEffort.effort } : {},
|
|
50826
51002
|
cwd,
|
|
50827
51003
|
claudeConfigDir,
|