File size: 1,989 Bytes
68d7816
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { createDecorator } from "#/_base/di/instantiation";

export const TOWER_TOOL_NAMES = [
  'TowerPlan',
  'TowerSpawn',
  'TowerMerge',
  'TowerTeardown',
  'TowerSend',
  'TowerInbox',
  'TowerFinding',
  'TowerReview',
  'TowerMission',
  'TowerStatus',
] as const;

export const TOWER_WORKER_PROFILE = 'tower-worker';

export function hasPinnedPermissionMode(profileName: string | undefined): boolean {
  return profileName === TOWER_WORKER_PROFILE;
}

export const TOWER_FLAG_ID = 'tower';

export type TowerEnterFailure =
  | {
      readonly entered: false;
      readonly reason: 'not-main-agent' | 'experiment-off' | 'feature-not-assembled';
    }
  | {
      readonly entered: false;
      readonly reason: 'owned-by-live-session';
      readonly owner: string;
      readonly ownerTitle?: string;
    };

export type TowerEnterResult = { readonly entered: true } | TowerEnterFailure;

export function towerEnterFailureMessage(failure: TowerEnterFailure): string {
  switch (failure.reason) {
    case 'not-main-agent':
      return 'tower mode is only supported by the main agent';
    case 'experiment-off':
      return 'the tower experiment is disabled; enable it with KIMI_CODE_EXPERIMENTAL_TOWER=1 or `[experimental] tower = true` in config.toml';
    case 'feature-not-assembled':
      return 'the tower feature is not assembled in this process; a restart is required';
    case 'owned-by-live-session': {
      const owner =
        failure.ownerTitle === undefined
          ? failure.owner
          : `${failure.ownerTitle} (${failure.owner})`;
      return `another live session owns the workspace tower (session ${owner})`;
    }
  }
}

export interface IAgentTowerService {
  readonly _serviceBrand: undefined;

  readonly isActive: boolean;
  readonly requestedBase: string | undefined;
  enter(base?: string): Promise<TowerEnterResult>;
  exit(): Promise<void>;
}

export const IAgentTowerService = createDecorator<IAgentTowerService>('agentTowerService');