@dotobokuri/fleet-console 1.65.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 +137 -4
- package/dist/client/assets/{_baseUniq-DyzqDsbR.js → _baseUniq-rDf4uMQX.js} +1 -1
- package/dist/client/assets/{arc-D9PB38OE.js → arc-btPQ2GHn.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-0L3Tlker.js → architectureDiagram-Q4EWVU46-DG6KDx34.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-BCAdqHmo.js → blockDiagram-DXYQGD6D-XUrLsQey.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-oK3f-N6i.js → c4Diagram-AHTNJAMY-DuXkZ8b1.js} +1 -1
- package/dist/client/assets/channel-CXR6clX_.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-CIYxtKO7.js → chunk-4BX2VUAB-C2tTKvHv.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-CKA_-tPR.js → chunk-4TB4RGXK-C5bwM8_h.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-ArIbE5m1.js → chunk-55IACEB6-BhcOy6C-.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-bGzMBuDL.js → chunk-EDXVE4YY-TOZwStuB.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-CZUkX3ry.js → chunk-FMBD7UC4-B8JSJHVV.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-CNXmIVXX.js → chunk-OYMX7WX6-BsNJ9iub.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-B3t4h1MD.js → chunk-QZHKN3VN-BhHSM1D6.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-CdGF0f8H.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-BESjfcni.js → cose-bilkent-S5V4N54A-D5mwO2NV.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-WpQhPw2a.js → dagre-KV5264BT-5fSh4g2E.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-BfAkutIX.js → diagram-5BDNPKRD-CtCGKgkm.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-C9I16SLL.js → diagram-G4DWMVQ6-CmGVsepF.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-CVJMM2zJ.js → diagram-MMDJMWI5-BR9Rfnad.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-DTqr7jJ3.js → diagram-TYMM5635-C9kuBFny.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-B09ElCdB.js → erDiagram-SMLLAGMA-BlL5tH_h.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-C93jg-t6.js → flowDiagram-DWJPFMVM-IUe6EFlH.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-5Js2lpdY.js → ganttDiagram-T4ZO3ILL-G-CTHnXi.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-BxGzg1Rc.js → gitGraphDiagram-UUTBAWPF-COUsDQ0n.js} +1 -1
- package/dist/client/assets/{graph-BkRyh4eN.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-DZPp1lR6.js → infoDiagram-42DDH7IO-DbNkXGyd.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-CXTuQ2Bb.js → ishikawaDiagram-UXIWVN3A-Iqt-Zs6v.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY--u6tYqhF.js → journeyDiagram-VCZTEJTY-m7TrTD61.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-CGMEohiQ.js → kanban-definition-6JOO6SKY-Df5KWqsi.js} +1 -1
- package/dist/client/assets/{layout-Bzu8ET7F.js → layout-BtA7fX7y.js} +1 -1
- package/dist/client/assets/{linear-B6htRUTP.js → linear-DVL8mywl.js} +1 -1
- package/dist/client/assets/{mermaid.core-CtpLAI-c.js → mermaid.core-CmjUZw2x.js} +4 -4
- package/dist/client/assets/{min-CEURoL5k.js → min-BTu70auM.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-B-HiXlEN.js → mindmap-definition-QFDTVHPH-BYpo-Mnc.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-DQgiLkTU.js → pieDiagram-DEJITSTG-B8zFmcim.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-xLh7CKRW.js → quadrantDiagram-34T5L4WZ-CMYVBi7F.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-O1SOxLMB.js → requirementDiagram-MS252O5E-BFeVMKvJ.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-D-mh4ZYc.js → sankeyDiagram-XADWPNL6-D2I70l9E.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-Dp2XhLFP.js → sequenceDiagram-FGHM5R23-zawVvGJJ.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-UQkaQPQt.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-DDMfKpma.js → timeline-definition-GMOUNBTQ-0gfoVpmY.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-DaGxBzx2.js → vennDiagram-DHZGUBPP-CuaEOGH2.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-DBNvUuF6.js → wardley-RL74JXVD-C-H0Svof.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-IbDED74Y.js → wardleyDiagram-NUSXRM2D-MQjjZFwh.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-0RafK-TZ.js → xychartDiagram-5P7HB3ND-BhTAVqtf.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/ledger/routes.mjs +130 -1
- package/dist/fleet-plugins/quota/routes.mjs +130 -1
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +130 -1
- package/dist/fleet-plugins/terminal/routes.mjs +344 -39
- package/dist/fleet.mjs +137 -4
- package/package.json +1 -1
- package/dist/client/assets/channel-CzEHIBah.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-jNK4g1rr.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-jNK4g1rr.js +0 -1
- package/dist/client/assets/clone-DggrGKv8.js +0 -1
- package/dist/client/assets/index-BSVaW3Ov.js +0 -465
- package/dist/client/assets/index-DxjgOu3C.css +0 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-CRw5Ot78.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 1M (1000000) variants on the same upstream bases",
|
|
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",
|
|
@@ -20967,6 +20983,135 @@ var models_default = {
|
|
|
20967
20983
|
],
|
|
20968
20984
|
benchmarkKey: "gpt-5.6-luna"
|
|
20969
20985
|
},
|
|
20986
|
+
{
|
|
20987
|
+
modelId: "gpt-5.6-sol-524k",
|
|
20988
|
+
name: "GPT-5.6-Sol-524K",
|
|
20989
|
+
capabilityClass: "flagship",
|
|
20990
|
+
providerModelId: "gpt-5.6-sol",
|
|
20991
|
+
contextWindow: 524288,
|
|
20992
|
+
effort: {
|
|
20993
|
+
supported: true,
|
|
20994
|
+
levels: [
|
|
20995
|
+
"low",
|
|
20996
|
+
"medium",
|
|
20997
|
+
"high",
|
|
20998
|
+
"xhigh",
|
|
20999
|
+
"max"
|
|
21000
|
+
]
|
|
21001
|
+
},
|
|
21002
|
+
aliases: [
|
|
21003
|
+
"gpt-5.6-sol-524k"
|
|
21004
|
+
],
|
|
21005
|
+
benchmarkKey: "gpt-5.6-sol"
|
|
21006
|
+
},
|
|
21007
|
+
{
|
|
21008
|
+
modelId: "gpt-5.6-sol-524k-fast",
|
|
21009
|
+
name: "GPT-5.6-Sol-524K-Fast",
|
|
21010
|
+
capabilityClass: "flagship",
|
|
21011
|
+
providerModelId: "gpt-5.6-sol",
|
|
21012
|
+
serviceTier: "priority",
|
|
21013
|
+
contextWindow: 524288,
|
|
21014
|
+
effort: {
|
|
21015
|
+
supported: true,
|
|
21016
|
+
levels: [
|
|
21017
|
+
"low",
|
|
21018
|
+
"medium",
|
|
21019
|
+
"high",
|
|
21020
|
+
"xhigh",
|
|
21021
|
+
"max"
|
|
21022
|
+
]
|
|
21023
|
+
},
|
|
21024
|
+
aliases: [
|
|
21025
|
+
"gpt-5.6-sol-524k-fast"
|
|
21026
|
+
],
|
|
21027
|
+
benchmarkKey: "gpt-5.6-sol"
|
|
21028
|
+
},
|
|
21029
|
+
{
|
|
21030
|
+
modelId: "gpt-5.6-luna-524k",
|
|
21031
|
+
name: "GPT-5.6-Luna-524K",
|
|
21032
|
+
capabilityClass: "light",
|
|
21033
|
+
providerModelId: "gpt-5.6-luna",
|
|
21034
|
+
contextWindow: 524288,
|
|
21035
|
+
effort: {
|
|
21036
|
+
supported: true,
|
|
21037
|
+
levels: [
|
|
21038
|
+
"low",
|
|
21039
|
+
"medium",
|
|
21040
|
+
"high",
|
|
21041
|
+
"xhigh",
|
|
21042
|
+
"max"
|
|
21043
|
+
]
|
|
21044
|
+
},
|
|
21045
|
+
aliases: [
|
|
21046
|
+
"gpt-5.6-luna-524k"
|
|
21047
|
+
],
|
|
21048
|
+
benchmarkKey: "gpt-5.6-luna"
|
|
21049
|
+
},
|
|
21050
|
+
{
|
|
21051
|
+
modelId: "gpt-5.6-luna-524k-fast",
|
|
21052
|
+
name: "GPT-5.6-Luna-524K-Fast",
|
|
21053
|
+
capabilityClass: "light",
|
|
21054
|
+
providerModelId: "gpt-5.6-luna",
|
|
21055
|
+
serviceTier: "priority",
|
|
21056
|
+
contextWindow: 524288,
|
|
21057
|
+
effort: {
|
|
21058
|
+
supported: true,
|
|
21059
|
+
levels: [
|
|
21060
|
+
"low",
|
|
21061
|
+
"medium",
|
|
21062
|
+
"high",
|
|
21063
|
+
"xhigh",
|
|
21064
|
+
"max"
|
|
21065
|
+
]
|
|
21066
|
+
},
|
|
21067
|
+
aliases: [
|
|
21068
|
+
"gpt-5.6-luna-524k-fast"
|
|
21069
|
+
],
|
|
21070
|
+
benchmarkKey: "gpt-5.6-luna"
|
|
21071
|
+
},
|
|
21072
|
+
{
|
|
21073
|
+
modelId: "gpt-5.6-terra-524k",
|
|
21074
|
+
name: "GPT-5.6-Terra-524K",
|
|
21075
|
+
capabilityClass: "standard",
|
|
21076
|
+
providerModelId: "gpt-5.6-terra",
|
|
21077
|
+
contextWindow: 524288,
|
|
21078
|
+
effort: {
|
|
21079
|
+
supported: true,
|
|
21080
|
+
levels: [
|
|
21081
|
+
"low",
|
|
21082
|
+
"medium",
|
|
21083
|
+
"high",
|
|
21084
|
+
"xhigh",
|
|
21085
|
+
"max"
|
|
21086
|
+
]
|
|
21087
|
+
},
|
|
21088
|
+
aliases: [
|
|
21089
|
+
"gpt-5.6-terra-524k"
|
|
21090
|
+
],
|
|
21091
|
+
benchmarkKey: "gpt-5.6-terra"
|
|
21092
|
+
},
|
|
21093
|
+
{
|
|
21094
|
+
modelId: "gpt-5.6-terra-524k-fast",
|
|
21095
|
+
name: "GPT-5.6-Terra-524K-Fast",
|
|
21096
|
+
capabilityClass: "standard",
|
|
21097
|
+
providerModelId: "gpt-5.6-terra",
|
|
21098
|
+
serviceTier: "priority",
|
|
21099
|
+
contextWindow: 524288,
|
|
21100
|
+
effort: {
|
|
21101
|
+
supported: true,
|
|
21102
|
+
levels: [
|
|
21103
|
+
"low",
|
|
21104
|
+
"medium",
|
|
21105
|
+
"high",
|
|
21106
|
+
"xhigh",
|
|
21107
|
+
"max"
|
|
21108
|
+
]
|
|
21109
|
+
},
|
|
21110
|
+
aliases: [
|
|
21111
|
+
"gpt-5.6-terra-524k-fast"
|
|
21112
|
+
],
|
|
21113
|
+
benchmarkKey: "gpt-5.6-terra"
|
|
21114
|
+
},
|
|
20970
21115
|
{
|
|
20971
21116
|
modelId: "gpt-5.6-sol-1m",
|
|
20972
21117
|
name: "GPT-5.6-Sol-1M",
|
|
@@ -48476,6 +48621,18 @@ var AgentChatSession = class {
|
|
|
48476
48621
|
* 답은 턴이 끝난 뒤에 오므로(실측), 그 사이 새 턴이 시작했다면 그 값은 남의 턴 자리에 앉는다.
|
|
48477
48622
|
*/
|
|
48478
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;
|
|
48479
48636
|
constructor(operationId, seed, createSdk) {
|
|
48480
48637
|
this.operationId = operationId;
|
|
48481
48638
|
this.seed = seed;
|
|
@@ -48812,25 +48969,33 @@ var AgentChatSession = class {
|
|
|
48812
48969
|
});
|
|
48813
48970
|
}
|
|
48814
48971
|
/**
|
|
48815
|
-
*
|
|
48972
|
+
* 자식에게 문맥 **내역**을 묻고, 답이 오면 저널에 싣는다. 두 경계에서 불린다 — 턴을 보내기
|
|
48973
|
+
* 직전(`"start"`)과 턴이 닫힌 직후(`"end"`).
|
|
48816
48974
|
*
|
|
48817
|
-
*
|
|
48818
|
-
*
|
|
48819
|
-
*
|
|
48975
|
+
* 왕복이 느리다는 것이 이 배선의 전제다(실측 21~88초, 요청 하나에 약 30초, 직렬 큐). 그래서
|
|
48976
|
+
* 총량은 이 채널에 맡기지 않고 `message_delta` usage가 진다. 여기서 얻는 것은 카테고리 분해 —
|
|
48977
|
+
* 그것만은 control 채널이 유일한 출처다.
|
|
48820
48978
|
*
|
|
48821
|
-
*
|
|
48822
|
-
*
|
|
48979
|
+
* 턴 중에는 아예 묻지 않는다. 자식이 턴이 시작되면 control을 닫아 +0ms의 요청만 답을 받고
|
|
48980
|
+
* 그 뒤는 전부 "Query closed before response received"로 끝난다(실측). 유휴 폴링도 하지 않는다 —
|
|
48981
|
+
* 답은 오지만 요청마다 30초를 태우고 큐만 밀린다.
|
|
48823
48982
|
*
|
|
48824
48983
|
* 응답을 기다리지 않는 이유는 스트림 때문이다: 여기서 await하면 첫 메시지 소비가 그만큼 늦다.
|
|
48825
|
-
* 늦게 도착한 답도 같은 턴의 시작 시점 값이므로, 그때 실어도 뜻이 달라지지 않는다.
|
|
48826
48984
|
*/
|
|
48827
|
-
|
|
48985
|
+
requestContextSnapshot(session, asOf) {
|
|
48986
|
+
if (this.contextInFlight) return;
|
|
48828
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
|
+
};
|
|
48829
48993
|
try {
|
|
48830
|
-
void session.getContextUsage().then((
|
|
48831
|
-
|
|
48832
|
-
}
|
|
48994
|
+
void session.getContextUsage().then(settle, () => {
|
|
48995
|
+
this.contextInFlight = false;
|
|
48996
|
+
});
|
|
48833
48997
|
} catch {
|
|
48998
|
+
this.contextInFlight = false;
|
|
48834
48999
|
}
|
|
48835
49000
|
}
|
|
48836
49001
|
/**
|
|
@@ -48844,25 +49009,100 @@ var AgentChatSession = class {
|
|
|
48844
49009
|
* 예약분(자동 압축 여유)과 남은 자리는 **쓴 것이 아니다**. 같은 목록에 두면 합이 언제나 창
|
|
48845
49010
|
* 전체가 되어 미터가 항상 100%를 가리킨다.
|
|
48846
49011
|
*/
|
|
48847
|
-
pushContext(usage4) {
|
|
49012
|
+
pushContext(usage4, asOf) {
|
|
49013
|
+
this.observedClaudeCoordinate = usage4.max;
|
|
48848
49014
|
const spent = usage4.categories.filter((category) => !category.deferred && category.tokens > 0 && !CONTEXT_UNSPENT.has(category.name));
|
|
48849
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
|
+
}));
|
|
48850
49021
|
this.push({
|
|
48851
49022
|
kind: "context",
|
|
48852
|
-
|
|
48853
|
-
|
|
48854
|
-
|
|
48855
|
-
|
|
48856
|
-
|
|
48857
|
-
...
|
|
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
|
+
} : {},
|
|
48858
49037
|
...usage4.mcpTools.length > 0 ? {
|
|
48859
49038
|
mcpTools: usage4.mcpTools.map((tool) => ({
|
|
48860
49039
|
name: tool.server ? `${tool.server} \xB7 ${tool.name}` : tool.name,
|
|
48861
|
-
tokens: tool.tokens
|
|
49040
|
+
tokens: window ? window.unproject(tool.tokens) : tool.tokens
|
|
48862
49041
|
}))
|
|
48863
49042
|
} : {}
|
|
48864
49043
|
});
|
|
48865
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
|
+
}
|
|
48866
49106
|
push(event) {
|
|
48867
49107
|
const entry = { seq: ++this.seq, event };
|
|
48868
49108
|
if (event.kind === "job-progress") {
|
|
@@ -48996,6 +49236,7 @@ var AgentChatSession = class {
|
|
|
48996
49236
|
if (this.latestSessionId !== this.reportedSessionId) this.syncProviderSessionOnce();
|
|
48997
49237
|
}
|
|
48998
49238
|
this.rememberJobOutput(message);
|
|
49239
|
+
this.trackLiveContext(message);
|
|
48999
49240
|
for (const event of chatEventsFromSdkMessage(message, { cwd: this.seed.cwd, toolNames: this.toolNames })) {
|
|
49000
49241
|
this.ingest(event);
|
|
49001
49242
|
}
|
|
@@ -49073,10 +49314,13 @@ var AgentChatSession = class {
|
|
|
49073
49314
|
});
|
|
49074
49315
|
this.abandonAsks("The turn ended before the question was answered.");
|
|
49075
49316
|
this.seed.reportActivity(false);
|
|
49317
|
+
this.liveContextTotal = null;
|
|
49076
49318
|
const awaiting = this.awaitingTurn;
|
|
49077
49319
|
this.awaitingTurn = null;
|
|
49078
49320
|
awaiting?.();
|
|
49079
49321
|
this.releaseTurnCloseWaiters();
|
|
49322
|
+
const session = this.session;
|
|
49323
|
+
if (session) this.requestContextSnapshot(session, "end");
|
|
49080
49324
|
}
|
|
49081
49325
|
/** 자리가 비었음을 줄 서 있던 디스패치들에게 알린다. 결말 하나가 전부를 깨운다. */
|
|
49082
49326
|
releaseTurnCloseWaiters() {
|
|
@@ -49150,7 +49394,7 @@ var AgentChatSession = class {
|
|
|
49150
49394
|
const settled = new Promise((resolve3) => {
|
|
49151
49395
|
this.awaitingTurn = resolve3;
|
|
49152
49396
|
});
|
|
49153
|
-
this.
|
|
49397
|
+
this.requestContextSnapshot(session, "start");
|
|
49154
49398
|
session.send(text2);
|
|
49155
49399
|
this.turnReachedChild = true;
|
|
49156
49400
|
await settled;
|
|
@@ -49289,6 +49533,21 @@ var AgentChatRegistry = class {
|
|
|
49289
49533
|
await Promise.all([...operationIds].map((operationId) => this.dispose(operationId)));
|
|
49290
49534
|
}
|
|
49291
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
|
+
}
|
|
49292
49551
|
|
|
49293
49552
|
// ../fleet-plugins/terminal/server/agent-api/chat-ws.ts
|
|
49294
49553
|
var MAX_CHAT_ANSWER_MESSAGE_CHARS = 2e3;
|
|
@@ -49401,6 +49660,15 @@ var ANALYSIS_ERROR_CODES = {
|
|
|
49401
49660
|
var ANALYST_GATEWAY_CLI_ID = "claude-gateway";
|
|
49402
49661
|
var ANALYST_DEFAULT_MODEL = "sonnet";
|
|
49403
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
|
+
}
|
|
49404
49672
|
var NATIVE_CLAUDE_LABELS = {
|
|
49405
49673
|
"fable[1m]": "Claude Fable",
|
|
49406
49674
|
sonnet: "Claude Sonnet",
|
|
@@ -49410,26 +49678,33 @@ function nativeClaudeAnalystModels() {
|
|
|
49410
49678
|
return NATIVE_CLAUDE_MODEL_ALIASES.map((modelId) => ({
|
|
49411
49679
|
modelId,
|
|
49412
49680
|
name: NATIVE_CLAUDE_LABELS[modelId] ?? modelId,
|
|
49413
|
-
effort: { supported: true, levels: [...
|
|
49681
|
+
effort: { supported: true, levels: [...ANALYST_EFFORT_LEVELS] }
|
|
49414
49682
|
}));
|
|
49415
49683
|
}
|
|
49416
49684
|
function resolveAnalysisGatewayBaseUrl(origin) {
|
|
49417
49685
|
return `${origin.replace(/\/+$/u, "")}/plugins/terminal/${AI_GATEWAY_ROUTE_SEGMENT}`;
|
|
49418
49686
|
}
|
|
49419
49687
|
function buildAnalysisCatalog(nativeModels, gatewayModels, available) {
|
|
49420
|
-
const native = nativeModels.map((model) =>
|
|
49421
|
-
|
|
49422
|
-
|
|
49423
|
-
|
|
49424
|
-
|
|
49425
|
-
|
|
49426
|
-
|
|
49427
|
-
|
|
49428
|
-
|
|
49429
|
-
|
|
49430
|
-
|
|
49431
|
-
effortLevels
|
|
49432
|
-
|
|
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
|
+
});
|
|
49433
49708
|
const models = [...native, ...gateway];
|
|
49434
49709
|
return {
|
|
49435
49710
|
clis: [{
|
|
@@ -49446,7 +49721,7 @@ function analysisError(code, message) {
|
|
|
49446
49721
|
return { error: { code, message } };
|
|
49447
49722
|
}
|
|
49448
49723
|
function isAnalysisSelection(catalog, value) {
|
|
49449
|
-
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;
|
|
49450
49725
|
const cli = catalog.clis.find((candidate) => candidate.cliId === value.cliId);
|
|
49451
49726
|
if (!cli?.available) return false;
|
|
49452
49727
|
const model = cli.models.find((candidate) => candidate.id === value.model);
|
|
@@ -49455,9 +49730,9 @@ function isAnalysisSelection(catalog, value) {
|
|
|
49455
49730
|
return typeof value.effort === "string" && value.effort.length > 0 && model.effortLevels.includes(value.effort);
|
|
49456
49731
|
}
|
|
49457
49732
|
function isMessageBody(value) {
|
|
49458
|
-
return
|
|
49733
|
+
return isRecord15(value) && hasExactKeys(value, ["text"]) && typeof value.text === "string" && value.text.trim().length > 0;
|
|
49459
49734
|
}
|
|
49460
|
-
function
|
|
49735
|
+
function isRecord15(value) {
|
|
49461
49736
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49462
49737
|
}
|
|
49463
49738
|
function hasExactKeys(value, keys) {
|
|
@@ -50024,6 +50299,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50024
50299
|
}
|
|
50025
50300
|
const launchOptions = readLaunchOptions(body, cliId, res);
|
|
50026
50301
|
if (launchOptions === false) return true;
|
|
50302
|
+
const geometry = readOptionalGeometry(body?.geometry, res);
|
|
50303
|
+
if (geometry === false) return true;
|
|
50027
50304
|
if (body?.prompt !== void 0 && typeof body.prompt !== "string") {
|
|
50028
50305
|
ctx.host.http.writeJson(res, 400, { error: "invalid_prompt" });
|
|
50029
50306
|
return true;
|
|
@@ -50064,7 +50341,8 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50064
50341
|
...launchOptions,
|
|
50065
50342
|
...composedPrompt ? { prompt: composedPrompt } : {},
|
|
50066
50343
|
...attachmentIds.length > 0 ? { attachmentIds } : {},
|
|
50067
|
-
...chatBorn ? { chatBorn: true } : {}
|
|
50344
|
+
...chatBorn ? { chatBorn: true } : {},
|
|
50345
|
+
...geometry ? { geometry } : {}
|
|
50068
50346
|
});
|
|
50069
50347
|
} catch (error51) {
|
|
50070
50348
|
if (attachmentIds.length > 0) launchAttachments.unreserve(attachmentIds);
|
|
@@ -50080,6 +50358,24 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50080
50358
|
}
|
|
50081
50359
|
return value;
|
|
50082
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
|
+
}
|
|
50083
50379
|
function readLaunchOptions(body, cliId, res) {
|
|
50084
50380
|
if (body?.model !== void 0 && typeof body.model !== "string" || body?.effort !== void 0 && typeof body.effort !== "string") {
|
|
50085
50381
|
ctx.host.http.writeJson(res, 400, { error: "invalid_launch_option" });
|
|
@@ -50204,6 +50500,7 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50204
50500
|
// "transcript 부재는 상실이 아니라 아직 첫 턴 전"이라는 뜻을 durable하게 남긴다.
|
|
50205
50501
|
...launchOptions.chatBorn ? { [CHAT_MODE_PAYLOAD_KEY]: true, [CHAT_BORN_PAYLOAD_KEY]: true } : {}
|
|
50206
50502
|
},
|
|
50503
|
+
...launchOptions.geometry ? { geometry: launchOptions.geometry } : {},
|
|
50207
50504
|
createdAt: session.createdAt
|
|
50208
50505
|
});
|
|
50209
50506
|
if (launchOptions.chatBorn) {
|
|
@@ -50684,6 +50981,9 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50684
50981
|
});
|
|
50685
50982
|
} catch {
|
|
50686
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;
|
|
50687
50987
|
const chatSkillOverrides = buildDisabledSkillOverrides(GATEWAY_DISABLED_CLAUDE_SKILLS);
|
|
50688
50988
|
const systemPromptMode = deps.globalOptionsService.load().claudeGatewaySystemPromptMode ?? "append";
|
|
50689
50989
|
const systemPrompt = systemPromptMode === "off" ? void 0 : { mode: systemPromptMode, text: createSystemPromptBuilder().build() };
|
|
@@ -50693,6 +50993,11 @@ async function createAgentApi(ctx, terminalRuntime, deps) {
|
|
|
50693
50993
|
seed: {
|
|
50694
50994
|
baseUrl: gatewayBaseUrl,
|
|
50695
50995
|
model,
|
|
50996
|
+
// 자식은 창이 500k인 모델도 자기 200k 좌표로 재고, 그 좌표를 물어보는 모든 표면에 그대로
|
|
50997
|
+
// 말한다. 실제 창과 투영에 쓰인 압축 정책을 함께 실어야 세션이 그것을 되돌릴 수 있다.
|
|
50998
|
+
// 네이티브 Claude 모델은 카탈로그에 없으므로 두 값 없이 지나가고 오늘의 숫자를 유지한다.
|
|
50999
|
+
...gatewayContextWindow === void 0 ? {} : { contextWindow: gatewayContextWindow },
|
|
51000
|
+
...gatewayCompactCeiling === void 0 ? {} : { compactCeiling: gatewayCompactCeiling },
|
|
50696
51001
|
...launchEffort ? { effort: launchEffort.effort } : {},
|
|
50697
51002
|
cwd,
|
|
50698
51003
|
claudeConfigDir,
|