github-issue-tower-defence-management 2.1.1 → 2.2.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/CHANGELOG.md +14 -0
- package/README.md +8 -0
- package/bin/adapter/entry-points/cli/fleetConfig.js +30 -12
- package/bin/adapter/entry-points/cli/fleetConfig.js.map +1 -1
- package/bin/adapter/entry-points/cli/index.js +5 -0
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/consoleOperationApi.js +6 -4
- package/bin/adapter/entry-points/console/consoleOperationApi.js.map +1 -1
- package/bin/adapter/entry-points/console/ui-dist/assets/{index-lT5OKx7e.js → index-BVyeR7xJ.js} +2 -2
- package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/bin/adapter/entry-points/console/webServer.js +0 -4
- package/bin/adapter/entry-points/console/webServer.js.map +1 -1
- package/bin/domain/usecases/StartPreparationUseCase.js +13 -12
- package/bin/domain/usecases/StartPreparationUseCase.js.map +1 -1
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/fleetConfig.test.ts +96 -0
- package/src/adapter/entry-points/cli/fleetConfig.ts +51 -6
- package/src/adapter/entry-points/cli/index.test.ts +2 -0
- package/src/adapter/entry-points/cli/index.ts +16 -0
- package/src/adapter/entry-points/console/consoleOperationApi.test.ts +60 -32
- package/src/adapter/entry-points/console/consoleOperationApi.ts +6 -7
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +12 -17
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.stories.tsx +1 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.test.tsx +85 -0
- package/src/adapter/entry-points/console/ui/src/features/console/components/list/ConsoleStoryList.tsx +73 -1
- package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +53 -16
- package/src/adapter/entry-points/console/ui-dist/assets/{index-lT5OKx7e.js → index-BVyeR7xJ.js} +2 -2
- package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
- package/src/adapter/entry-points/console/webServer.ts +0 -8
- package/src/domain/usecases/StartPreparationUseCase.test.ts +97 -0
- package/src/domain/usecases/StartPreparationUseCase.ts +13 -3
- package/types/adapter/entry-points/cli/fleetConfig.d.ts +6 -0
- package/types/adapter/entry-points/cli/fleetConfig.d.ts.map +1 -1
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts +1 -2
- package/types/adapter/entry-points/console/consoleOperationApi.d.ts.map +1 -1
- package/types/adapter/entry-points/console/webServer.d.ts +0 -2
- package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts +3 -1
- package/types/domain/usecases/StartPreparationUseCase.d.ts.map +1 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>TDPM Console</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BVyeR7xJ.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-CLHvrafO.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -3,7 +3,6 @@ import * as fs from 'fs';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
|
|
5
5
|
import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
6
|
-
import { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/ProjectRepository';
|
|
7
6
|
import { Project } from '../../../domain/entities/Project';
|
|
8
7
|
import {
|
|
9
8
|
CONSOLE_LIST_TAB_NAMES,
|
|
@@ -240,7 +239,6 @@ export type WebServerOptions = {
|
|
|
240
239
|
resolveProjectRepository?: ConsoleProjectRepositoryResolver | null;
|
|
241
240
|
invalidateProject?: ((pjcode: string) => void) | null;
|
|
242
241
|
issueAttachmentRepository?: IssueAttachmentRepository | null;
|
|
243
|
-
projectRepository?: Pick<ProjectRepository, 'updateStoryList'> | null;
|
|
244
242
|
updateProjectCacheEntry?:
|
|
245
243
|
((pjcode: string, updatedProject: Project) => void) | null;
|
|
246
244
|
issueTitleStateCache?: IssueTitleStateCache | null;
|
|
@@ -574,18 +572,12 @@ const handleOperationApi = async (
|
|
|
574
572
|
}
|
|
575
573
|
const resolveIssueRepository =
|
|
576
574
|
options.resolveIssueRepository ?? ((): IssueRepository => issueRepository);
|
|
577
|
-
const projectRepository = options.projectRepository ?? null;
|
|
578
575
|
const context: ConsoleOperationContext = {
|
|
579
576
|
resolveIssueRepository,
|
|
580
577
|
resolveProject,
|
|
581
578
|
isPjcodeConfigured,
|
|
582
579
|
consoleDataOutputDir: options.consoleDataOutputDir,
|
|
583
580
|
issueAttachmentRepository: options.issueAttachmentRepository ?? null,
|
|
584
|
-
updateStoryList:
|
|
585
|
-
projectRepository !== null
|
|
586
|
-
? (project, stories) =>
|
|
587
|
-
projectRepository.updateStoryList(project, stories)
|
|
588
|
-
: null,
|
|
589
581
|
resolveProjectRepository: options.resolveProjectRepository ?? null,
|
|
590
582
|
invalidateProject: options.invalidateProject ?? null,
|
|
591
583
|
updateProjectCacheEntry: options.updateProjectCacheEntry ?? null,
|
|
@@ -7393,6 +7393,103 @@ describe('StartPreparationUseCase.getTokenConcurrentLimit', () => {
|
|
|
7393
7393
|
it('never lets a selection weight take the limit below one slot', () => {
|
|
7394
7394
|
expect(useCase.getTokenConcurrentLimit(0.1, 0.1, 0.01)).toBe(1);
|
|
7395
7395
|
});
|
|
7396
|
+
|
|
7397
|
+
it('uses normalConcurrentLimit as the full-speed ceiling when both utilizations are low', () => {
|
|
7398
|
+
expect(useCase.getTokenConcurrentLimit(0.1, 0.1, undefined, 10)).toBe(10);
|
|
7399
|
+
});
|
|
7400
|
+
|
|
7401
|
+
it('tapers from normalConcurrentLimit when utilization is above the threshold', () => {
|
|
7402
|
+
expect(useCase.getTokenConcurrentLimit(0.1, 0.9, undefined, 10)).toBe(5);
|
|
7403
|
+
});
|
|
7404
|
+
});
|
|
7405
|
+
|
|
7406
|
+
describe('StartPreparationUseCase.run normalConcurrentLimit', () => {
|
|
7407
|
+
it('applies a custom normalConcurrentLimit to cap token concurrency per token', async () => {
|
|
7408
|
+
const mockProject = createMockProject();
|
|
7409
|
+
const awaitingIssue = createMockIssue({
|
|
7410
|
+
url: 'https://github.com/user/repo/issues/1',
|
|
7411
|
+
status: 'Awaiting Workspace',
|
|
7412
|
+
story: 'some-story',
|
|
7413
|
+
});
|
|
7414
|
+
const mockProjectRepository = {
|
|
7415
|
+
getByUrl: jest.fn().mockResolvedValue(mockProject),
|
|
7416
|
+
createField: jest.fn().mockResolvedValue(undefined),
|
|
7417
|
+
updateAgentList: jest.fn().mockResolvedValue([]),
|
|
7418
|
+
};
|
|
7419
|
+
const mockIssueRepository = {
|
|
7420
|
+
getStoryObjectMap: jest
|
|
7421
|
+
.fn()
|
|
7422
|
+
.mockResolvedValue(createMockStoryObjectMap([awaitingIssue])),
|
|
7423
|
+
getAllOpened: jest.fn().mockResolvedValue([awaitingIssue]),
|
|
7424
|
+
updateStatus: jest.fn().mockResolvedValue(undefined),
|
|
7425
|
+
findRelatedOpenPRs: jest.fn().mockResolvedValue([]),
|
|
7426
|
+
getOpenPullRequest: jest.fn().mockResolvedValue(null),
|
|
7427
|
+
closePullRequest: jest.fn().mockResolvedValue(undefined),
|
|
7428
|
+
deletePullRequestBranch: jest.fn().mockResolvedValue(undefined),
|
|
7429
|
+
createCommentByUrl: jest.fn().mockResolvedValue(undefined),
|
|
7430
|
+
setIssueAgentField: jest.fn().mockResolvedValue(undefined),
|
|
7431
|
+
removeLabel: jest.fn().mockResolvedValue(undefined),
|
|
7432
|
+
};
|
|
7433
|
+
const mockLocalCommandRunner = {
|
|
7434
|
+
runCommand: jest
|
|
7435
|
+
.fn()
|
|
7436
|
+
.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 }),
|
|
7437
|
+
spawnInteractive: jest.fn(),
|
|
7438
|
+
};
|
|
7439
|
+
const token = 'token-a';
|
|
7440
|
+
const mockClaudeTokenUsageRepository = {
|
|
7441
|
+
ensureObservable: jest.fn().mockResolvedValue(undefined),
|
|
7442
|
+
getAvailableTokenUsages: jest.fn().mockResolvedValue([
|
|
7443
|
+
{
|
|
7444
|
+
token,
|
|
7445
|
+
name: 'token-a',
|
|
7446
|
+
fiveHourUtilization: 0.0,
|
|
7447
|
+
sevenDayUtilization: 0.0,
|
|
7448
|
+
fiveHourRejected: false,
|
|
7449
|
+
blocked: false,
|
|
7450
|
+
blockedUntilEpoch: 0,
|
|
7451
|
+
modelWeeklyLimits: {},
|
|
7452
|
+
selectionWeight: undefined,
|
|
7453
|
+
},
|
|
7454
|
+
]),
|
|
7455
|
+
getTokenInFlightCounts: jest.fn().mockResolvedValue({ [token]: 0 }),
|
|
7456
|
+
proxyBaseUrl: jest.fn().mockReturnValue('http://127.0.0.1:8787'),
|
|
7457
|
+
};
|
|
7458
|
+
const mockTakeOwnershipSpawnRepository = {
|
|
7459
|
+
listSpawns: jest.fn().mockReturnValue([]),
|
|
7460
|
+
listRunningIssueUrls: jest.fn().mockReturnValue([]),
|
|
7461
|
+
};
|
|
7462
|
+
const useCase = new StartPreparationUseCase(
|
|
7463
|
+
mockProjectRepository,
|
|
7464
|
+
mockIssueRepository,
|
|
7465
|
+
mockLocalCommandRunner,
|
|
7466
|
+
mockClaudeTokenUsageRepository,
|
|
7467
|
+
mockTakeOwnershipSpawnRepository,
|
|
7468
|
+
);
|
|
7469
|
+
|
|
7470
|
+
await useCase.run({
|
|
7471
|
+
projectUrl: 'https://github.com/users/user/projects/1',
|
|
7472
|
+
defaultAgentName: 'agent1',
|
|
7473
|
+
defaultLlmModelName: 'claude-opus',
|
|
7474
|
+
fallbackLlmModelName: null,
|
|
7475
|
+
defaultLlmAgentName: null,
|
|
7476
|
+
configFilePath: '/path/to/config.yml',
|
|
7477
|
+
maximumPreparingIssuesCount: 20,
|
|
7478
|
+
utilizationPercentageThreshold: 90,
|
|
7479
|
+
allowedIssueAuthors: ['testuser'],
|
|
7480
|
+
manager: 'manager-user',
|
|
7481
|
+
codexHomeCandidates: null,
|
|
7482
|
+
labelsAsLlmAgentName: null,
|
|
7483
|
+
normalConcurrentLimit: 10,
|
|
7484
|
+
});
|
|
7485
|
+
|
|
7486
|
+
expect(mockLocalCommandRunner.runCommand).toHaveBeenCalledTimes(1);
|
|
7487
|
+
expect(mockLocalCommandRunner.runCommand).toHaveBeenCalledWith(
|
|
7488
|
+
'aw',
|
|
7489
|
+
expect.any(Array),
|
|
7490
|
+
expect.anything(),
|
|
7491
|
+
);
|
|
7492
|
+
});
|
|
7396
7493
|
});
|
|
7397
7494
|
|
|
7398
7495
|
describe('StartPreparationUseCase.fetchSpawnCandidateBranchSources', () => {
|
|
@@ -19,7 +19,7 @@ import { issueReactivationTriggerIsPending } from './issueReactivationTriggerIsP
|
|
|
19
19
|
import { ensureAgentOptionAndGetId } from './ensureAgentOptionAndGetId';
|
|
20
20
|
import { isAuthorAuthorizedForAutoStatusCheck } from './isAuthorAuthorizedForAutoStatusCheck';
|
|
21
21
|
|
|
22
|
-
const NORMAL_CONCURRENT_LIMIT = 6;
|
|
22
|
+
export const NORMAL_CONCURRENT_LIMIT = 6;
|
|
23
23
|
const SEVEN_DAY_THROTTLE_START_THRESHOLD = 0.8;
|
|
24
24
|
const FIVE_HOUR_THROTTLE_START_THRESHOLD = 0.8;
|
|
25
25
|
export const DEFAULT_FALLBACK_LLM_MODEL_NAME = 'claude-opus-4-8';
|
|
@@ -163,26 +163,30 @@ export class StartPreparationUseCase {
|
|
|
163
163
|
private taperedConcurrentLimit = (
|
|
164
164
|
utilization: number,
|
|
165
165
|
throttleStartThreshold: number,
|
|
166
|
+
normalConcurrentLimit: number,
|
|
166
167
|
): number => {
|
|
167
168
|
if (utilization < throttleStartThreshold) {
|
|
168
|
-
return
|
|
169
|
+
return normalConcurrentLimit;
|
|
169
170
|
}
|
|
170
171
|
const remaining = (1 - utilization) / (1 - throttleStartThreshold);
|
|
171
|
-
return Math.max(1, Math.ceil(
|
|
172
|
+
return Math.max(1, Math.ceil(normalConcurrentLimit * remaining));
|
|
172
173
|
};
|
|
173
174
|
|
|
174
175
|
getTokenConcurrentLimit = (
|
|
175
176
|
fiveHourUtilization: number,
|
|
176
177
|
sevenDayUtilization: number,
|
|
177
178
|
selectionWeight?: number,
|
|
179
|
+
normalConcurrentLimit: number = NORMAL_CONCURRENT_LIMIT,
|
|
178
180
|
): number => {
|
|
179
181
|
const sevenDayLimit = this.taperedConcurrentLimit(
|
|
180
182
|
sevenDayUtilization,
|
|
181
183
|
SEVEN_DAY_THROTTLE_START_THRESHOLD,
|
|
184
|
+
normalConcurrentLimit,
|
|
182
185
|
);
|
|
183
186
|
const fiveHourLimit = this.taperedConcurrentLimit(
|
|
184
187
|
fiveHourUtilization,
|
|
185
188
|
FIVE_HOUR_THROTTLE_START_THRESHOLD,
|
|
189
|
+
normalConcurrentLimit,
|
|
186
190
|
);
|
|
187
191
|
const weight = selectionWeight ?? DEFAULT_SELECTION_WEIGHT;
|
|
188
192
|
return Math.max(
|
|
@@ -268,6 +272,7 @@ export class StartPreparationUseCase {
|
|
|
268
272
|
defaultModelName: string | null,
|
|
269
273
|
fallbackModelName: string | null,
|
|
270
274
|
maxConcurrent: number,
|
|
275
|
+
normalConcurrentLimit: number,
|
|
271
276
|
): {
|
|
272
277
|
tokens: string[];
|
|
273
278
|
effectiveCap: number;
|
|
@@ -317,6 +322,7 @@ export class StartPreparationUseCase {
|
|
|
317
322
|
usage.fiveHourUtilization,
|
|
318
323
|
usage.sevenDayUtilization,
|
|
319
324
|
usage.selectionWeight,
|
|
325
|
+
normalConcurrentLimit,
|
|
320
326
|
),
|
|
321
327
|
secondsUntilSevenDayReset: this.secondsUntilSevenDayReset(
|
|
322
328
|
usage,
|
|
@@ -414,7 +420,10 @@ export class StartPreparationUseCase {
|
|
|
414
420
|
codexHomeCandidates: string[] | null;
|
|
415
421
|
labelsAsLlmAgentName: string[] | null;
|
|
416
422
|
agents?: string[] | null;
|
|
423
|
+
normalConcurrentLimit?: number;
|
|
417
424
|
}): Promise<{ rotationOrder: RotationOrderEntry[] | null }> => {
|
|
425
|
+
const normalConcurrentLimit =
|
|
426
|
+
params.normalConcurrentLimit ?? NORMAL_CONCURRENT_LIMIT;
|
|
418
427
|
const tokenUsages =
|
|
419
428
|
await this.claudeTokenUsageRepository.getAvailableTokenUsages();
|
|
420
429
|
let rotationTokens: string[] | null = null;
|
|
@@ -450,6 +459,7 @@ export class StartPreparationUseCase {
|
|
|
450
459
|
params.defaultLlmModelName,
|
|
451
460
|
fallbackLlmModelName,
|
|
452
461
|
maximumPreparingIssuesCount,
|
|
462
|
+
normalConcurrentLimit,
|
|
453
463
|
);
|
|
454
464
|
if (selectedTokens.length === 0) {
|
|
455
465
|
console.warn(
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { LiveSessionOauthTokenSelectionSettings } from '../../../domain/usecases/LiveSessionOauthTokenSelectUseCase';
|
|
2
2
|
export declare const FLEET_CONFIG_FILE_PATH_ENVIRONMENT_VARIABLE = "TDPM_FLEET_CONFIG";
|
|
3
3
|
export declare const LIVE_SESSION_OAUTH_TOKEN_SELECTION_SECTION_KEY = "liveSessionOauthTokenSelection";
|
|
4
|
+
export declare const PREPARATION_WORKER_SECTION_KEY = "preparationWorker";
|
|
5
|
+
export type PreparationWorkerSettings = {
|
|
6
|
+
normalConcurrentLimit: number;
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_PREPARATION_WORKER_SETTINGS: PreparationWorkerSettings;
|
|
4
9
|
export declare const resolveFleetConfigFilePath: (cliValue: string | null) => string | null;
|
|
5
10
|
export declare const loadLiveSessionOauthTokenSelectionSettings: (fleetConfigFilePath: string | null) => LiveSessionOauthTokenSelectionSettings;
|
|
11
|
+
export declare const loadPreparationWorkerSettings: (fleetConfigFilePath: string | null) => PreparationWorkerSettings;
|
|
6
12
|
//# sourceMappingURL=fleetConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fleetConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/fleetConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,sCAAsC,EACvC,MAAM,6DAA6D,CAAC;
|
|
1
|
+
{"version":3,"file":"fleetConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/fleetConfig.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,sCAAsC,EACvC,MAAM,6DAA6D,CAAC;AAGrE,eAAO,MAAM,2CAA2C,sBAAsB,CAAC;AAE/E,eAAO,MAAM,8CAA8C,mCACzB,CAAC;AACnC,eAAO,MAAM,8BAA8B,sBAAsB,CAAC;AAElE,MAAM,MAAM,yBAAyB,GAAG;IACtC,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,mCAAmC,EAAE,yBAEjD,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,MAAM,GAAG,IAAI,KACtB,MAAM,GAAG,IAUX,CAAC;AA0DF,eAAO,MAAM,0CAA0C,GACrD,qBAAqB,MAAM,GAAG,IAAI,KACjC,sCAiDF,CAAC;AAEF,eAAO,MAAM,6BAA6B,GACxC,qBAAqB,MAAM,GAAG,IAAI,KACjC,yBAsBF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,YAAY,EACZ,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AAiPzB,eAAO,MAAM,OAAO,SAAgB,CAAC;AAwmCrC,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAGxD,CAAC;AAwCF,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EAAE,EACd,kBAAkB,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KACzC,OAAO,CAAC,IAAI,CAqCd,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Project } from '../../../domain/entities/Project';
|
|
2
2
|
import type { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
|
|
3
3
|
import type { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
4
4
|
import type { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/ProjectRepository';
|
|
@@ -20,7 +20,6 @@ export type ConsoleOperationContext = {
|
|
|
20
20
|
isPjcodeConfigured: ConsolePjcodeValidator;
|
|
21
21
|
consoleDataOutputDir: string | null;
|
|
22
22
|
issueAttachmentRepository: IssueAttachmentRepository | null;
|
|
23
|
-
updateStoryList: ((project: Project, stories: FieldOption[]) => Promise<FieldOption[]>) | null;
|
|
24
23
|
resolveProjectRepository: ConsoleProjectRepositoryResolver | null;
|
|
25
24
|
invalidateProject: ((pjcode: string) => void) | null;
|
|
26
25
|
updateProjectCacheEntry: ((pjcode: string, updatedProject: Project) => void) | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"consoleOperationApi.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/consoleOperationApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
2
|
import { IssueAttachmentRepository } from '../../../domain/usecases/adapter-interfaces/IssueAttachmentRepository';
|
|
3
3
|
import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
4
|
-
import { ProjectRepository } from '../../../domain/usecases/adapter-interfaces/ProjectRepository';
|
|
5
4
|
import { Project } from '../../../domain/entities/Project';
|
|
6
5
|
import { IssueTitleStateCache, PullRequestStatusCache } from './consoleReadApi';
|
|
7
6
|
import { ConsoleIssueRepositoryResolver, ConsolePjcodeValidator, ConsoleProjectRepositoryResolver, ConsoleProjectResolver } from './consoleOperationApi';
|
|
@@ -36,7 +35,6 @@ export type WebServerOptions = {
|
|
|
36
35
|
resolveProjectRepository?: ConsoleProjectRepositoryResolver | null;
|
|
37
36
|
invalidateProject?: ((pjcode: string) => void) | null;
|
|
38
37
|
issueAttachmentRepository?: IssueAttachmentRepository | null;
|
|
39
|
-
projectRepository?: Pick<ProjectRepository, 'updateStoryList'> | null;
|
|
40
38
|
updateProjectCacheEntry?: ((pjcode: string, updatedProject: Project) => void) | null;
|
|
41
39
|
issueTitleStateCache?: IssueTitleStateCache | null;
|
|
42
40
|
pullRequestStatusCache?: PullRequestStatusCache | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,uEAAuE,CAAC;AAClH,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AAC9F,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { LocalCommandRunner } from './adapter-interfaces/LocalCommandRunner';
|
|
|
5
5
|
import { ClaudeTokenUsageRepository } from './adapter-interfaces/ClaudeTokenUsageRepository';
|
|
6
6
|
import { TakeOwnershipSpawnRepository } from './adapter-interfaces/TakeOwnershipSpawnRepository';
|
|
7
7
|
import { ClaudeTokenUsage } from '../entities/ClaudeTokenUsage';
|
|
8
|
+
export declare const NORMAL_CONCURRENT_LIMIT = 6;
|
|
8
9
|
export declare const DEFAULT_FALLBACK_LLM_MODEL_NAME = "claude-opus-4-8";
|
|
9
10
|
export declare const SPAWN_CANDIDATE_BRANCH_SOURCE_CONCURRENCY = 8;
|
|
10
11
|
export type SpawnCandidateExclusionReason = 'dependedIssueUrls' | 'futureNextActionDate' | 'nextActionHourNotReached' | 'authorNotAllowed' | 'notAssignedToManager';
|
|
@@ -35,7 +36,7 @@ export declare class StartPreparationUseCase {
|
|
|
35
36
|
private secondsUntilSevenDayReset;
|
|
36
37
|
private compareBySevenDayDeadlineThenUtilization;
|
|
37
38
|
private taperedConcurrentLimit;
|
|
38
|
-
getTokenConcurrentLimit: (fiveHourUtilization: number, sevenDayUtilization: number, selectionWeight?: number) => number;
|
|
39
|
+
getTokenConcurrentLimit: (fiveHourUtilization: number, sevenDayUtilization: number, selectionWeight?: number, normalConcurrentLimit?: number) => number;
|
|
39
40
|
spawnCandidateExclusionReasonOf: (issue: Issue, allowedIssueAuthors: string[] | null, manager: string, now: Date) => SpawnCandidateExclusionReason | null;
|
|
40
41
|
fetchSpawnCandidateBranchSources: (issueUrls: string[]) => Promise<Map<string, SpawnCandidateBranchSource>>;
|
|
41
42
|
private selectRotationTokens;
|
|
@@ -54,6 +55,7 @@ export declare class StartPreparationUseCase {
|
|
|
54
55
|
codexHomeCandidates: string[] | null;
|
|
55
56
|
labelsAsLlmAgentName: string[] | null;
|
|
56
57
|
agents?: string[] | null;
|
|
58
|
+
normalConcurrentLimit?: number;
|
|
57
59
|
}) => Promise<{
|
|
58
60
|
rotationOrder: RotationOrderEntry[] | null;
|
|
59
61
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,kBAAkB,EACnB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAC7F,OAAO,EAAE,4BAA4B,EAAE,MAAM,mDAAmD,CAAC;AACjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"StartPreparationUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StartPreparationUseCase.ts"],"names":[],"mappings":"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"}
|