File size: 4,451 Bytes
4e23b01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
 * Klient-level global events — the public, typed, namespaced event surface.
 * Each registration binds a public event name to its underlying source (the
 * `IEventService` bus or one service's `onDid*` emitter) plus the zod schema
 * its payload must satisfy. Consumers never see the engine's `onDid`/`onWill`
 * naming; unknown bus event types are not forwarded.
 */

import { z } from 'zod';

import type { ConfigChangedEvent } from '@moonshot-ai/agent-core-v2/app/config/config';
import type { ModelsChangedEvent } from '@moonshot-ai/agent-core-v2/llm-adapter/model/model';
import type { ProvidersChangedEvent } from '@moonshot-ai/agent-core-v2/llm-adapter/provider/provider';
import type { ReloadSummary } from '@moonshot-ai/agent-core-v2/app/plugin/types';
import type { IOAuthService } from '@moonshot-ai/agent-core-v2/app/auth/auth';

import { stringDeltaSchema } from '../helpers.js';
import type { EventRegistration } from '../types.js';

/** Payload of `event.session.archived` on the global bus. */
export interface SessionArchivedPayload {
  readonly sessionId: string;
}

/** Payload of `session.meta.updated` on the global bus (`session/sessionMetadata/promptMetadata.ts`). */
export interface SessionMetaUpdatedPayload {
  readonly agentId: string;
  readonly sessionId: string;
  readonly title?: string;
  readonly patch: {
    readonly title?: string;
    readonly isCustomTitle?: boolean;
    readonly lastPrompt?: string;
  };
}

/** Payload of `event.model_catalog.changed` — same shape as an OAuth refresh result. */
export type CatalogChangedPayload = Awaited<
  ReturnType<IOAuthService['refreshOAuthProviderModels']>
>;

/** Public event name → payload type. Keys must stay in sync with `globalEvents`. */
export interface KlientEventPayloads {
  'config.changed': ConfigChangedEvent;
  'config.sectionChanged': ConfigChangedEvent;
  'kosong.providers.changed': ProvidersChangedEvent;
  'kosong.models.changed': ModelsChangedEvent;
  'plugins.reloaded': ReloadSummary;
  'session.archived': SessionArchivedPayload;
  'session.metaUpdated': SessionMetaUpdatedPayload;
  'kosong.changed': CatalogChangedPayload;
}

export type KlientEventName = keyof KlientEventPayloads;

const configChangedSchema = z.object({
  domain: z.string(),
  source: z.enum(['load', 'reload', 'set']),
  value: z.unknown(),
  previousValue: z.unknown(),
});

const reloadSummarySchema = z.object({
  added: z.array(z.string()),
  removed: z.array(z.string()),
  errors: z.array(z.object({ id: z.string(), message: z.string() })),
});

const sessionMetaUpdatedSchema = z.object({
  agentId: z.string(),
  sessionId: z.string(),
  title: z.string().optional(),
  patch: z.object({
    title: z.string().optional(),
    isCustomTitle: z.boolean().optional(),
    lastPrompt: z.string().optional(),
  }),
}) satisfies z.ZodType<SessionMetaUpdatedPayload>;

export const catalogChangedSchema = z.object({
  changed: z.array(
    z.object({
      provider_id: z.string(),
      provider_name: z.string(),
      added: z.number(),
      removed: z.number(),
    }),
  ),
  unchanged: z.array(z.string()),
  failed: z.array(z.object({ provider: z.string(), reason: z.string() })),
});

/** Public event name → source binding + payload schema. */
export const globalEvents = {
  'config.changed': {
    kind: 'emitter',
    service: 'configService',
    event: 'onDidChangeConfiguration',
    schema: configChangedSchema,
  },
  'config.sectionChanged': {
    kind: 'emitter',
    service: 'configService',
    event: 'onDidSectionChange',
    schema: configChangedSchema,
  },
  'kosong.providers.changed': {
    kind: 'emitter',
    service: 'providerService',
    event: 'onDidChangeProviders',
    schema: stringDeltaSchema,
  },
  'kosong.models.changed': {
    kind: 'emitter',
    service: 'modelService',
    event: 'onDidChangeModels',
    schema: stringDeltaSchema,
  },
  'plugins.reloaded': {
    kind: 'emitter',
    service: 'pluginService',
    event: 'onDidReload',
    schema: reloadSummarySchema,
  },
  'session.archived': {
    kind: 'bus',
    type: 'event.session.archived',
    schema: z.object({ sessionId: z.string() }),
  },
  'session.metaUpdated': {
    kind: 'bus',
    type: 'session.meta.updated',
    schema: sessionMetaUpdatedSchema,
  },
  'kosong.changed': {
    kind: 'bus',
    type: 'event.model_catalog.changed',
    schema: catalogChangedSchema,
  },
} satisfies Record<KlientEventName, EventRegistration>;