global.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import { ConfigV1 } from "@kirincode-ai/core/v1/config/config"
  2. import { EventV2 } from "@kirincode-ai/core/event"
  3. import { EventManifest } from "@/event-manifest"
  4. import { InstanceDisposed } from "@/server/event"
  5. import "@kirincode-ai/core/account"
  6. import "@/server/event"
  7. import { Schema } from "effect"
  8. import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
  9. import { described } from "./metadata"
  10. const GlobalHealth = Schema.Struct({
  11. healthy: Schema.Literal(true),
  12. version: Schema.String,
  13. })
  14. const SyncEventSchemas = EventManifest.Latest.values()
  15. .flatMap((definition) => {
  16. if (!definition.durable) return []
  17. return [
  18. Schema.Struct({
  19. type: Schema.Literal("sync"),
  20. id: EventV2.ID,
  21. syncEvent: Schema.Struct({
  22. type: Schema.Literal(EventV2.versionedType(definition.type, definition.durable.version)),
  23. id: EventV2.ID,
  24. seq: Schema.Finite,
  25. aggregateID: Schema.String,
  26. data: definition.data,
  27. }),
  28. }).annotate({ identifier: `SyncEvent.${definition.type}` }),
  29. ]
  30. })
  31. .toArray()
  32. const GlobalEventSchema = Schema.Struct({
  33. directory: Schema.String,
  34. project: Schema.optional(Schema.String),
  35. workspace: Schema.optional(Schema.String),
  36. payload: Schema.Union([
  37. ...EventManifest.Latest.values()
  38. .map((definition) =>
  39. Schema.Struct({ id: EventV2.ID, type: Schema.Literal(definition.type), properties: definition.data }),
  40. )
  41. .toArray(),
  42. InstanceDisposed,
  43. ...SyncEventSchemas,
  44. ]),
  45. }).annotate({ identifier: "GlobalEvent" })
  46. export const GlobalUpgradeInput = Schema.Struct({
  47. target: Schema.optional(Schema.String),
  48. })
  49. const GlobalUpgradeResult = Schema.Union([
  50. Schema.Struct({
  51. success: Schema.Literal(true),
  52. version: Schema.String,
  53. }),
  54. Schema.Struct({
  55. success: Schema.Literal(false),
  56. error: Schema.String,
  57. }),
  58. ])
  59. export const GlobalPaths = {
  60. health: "/global/health",
  61. event: "/global/event",
  62. config: "/global/config",
  63. dispose: "/global/dispose",
  64. upgrade: "/global/upgrade",
  65. } as const
  66. export const GlobalApi = HttpApi.make("global").add(
  67. HttpApiGroup.make("global")
  68. .add(
  69. HttpApiEndpoint.get("health", GlobalPaths.health, {
  70. success: described(GlobalHealth, "Health information"),
  71. }).annotateMerge(
  72. OpenApi.annotations({
  73. identifier: "global.health",
  74. summary: "Get health",
  75. description: "Get health information about the KirinCode server.",
  76. }),
  77. ),
  78. HttpApiEndpoint.get("event", GlobalPaths.event, {
  79. success: GlobalEventSchema,
  80. }).annotateMerge(
  81. OpenApi.annotations({
  82. identifier: "global.event",
  83. summary: "Get global events",
  84. description: "Subscribe to global events from the KirinCode system using server-sent events.",
  85. }),
  86. ),
  87. HttpApiEndpoint.get("configGet", GlobalPaths.config, {
  88. success: described(ConfigV1.Info, "Get global config info"),
  89. }).annotateMerge(
  90. OpenApi.annotations({
  91. identifier: "global.config.get",
  92. summary: "Get global configuration",
  93. description: "Retrieve the current global KirinCode configuration settings and preferences.",
  94. }),
  95. ),
  96. HttpApiEndpoint.patch("configUpdate", GlobalPaths.config, {
  97. payload: ConfigV1.Info,
  98. success: described(ConfigV1.Info, "Successfully updated global config"),
  99. error: HttpApiError.BadRequest,
  100. }).annotateMerge(
  101. OpenApi.annotations({
  102. identifier: "global.config.update",
  103. summary: "Update global configuration",
  104. description: "Update global KirinCode configuration settings and preferences.",
  105. }),
  106. ),
  107. HttpApiEndpoint.post("dispose", GlobalPaths.dispose, {
  108. success: described(Schema.Boolean, "Global disposed"),
  109. }).annotateMerge(
  110. OpenApi.annotations({
  111. identifier: "global.dispose",
  112. summary: "Dispose instance",
  113. description: "Clean up and dispose all KirinCode instances, releasing all resources.",
  114. }),
  115. ),
  116. HttpApiEndpoint.post("upgrade", GlobalPaths.upgrade, {
  117. payload: [HttpApiSchema.NoContent, GlobalUpgradeInput],
  118. success: described(GlobalUpgradeResult, "Upgrade result"),
  119. error: HttpApiError.BadRequest,
  120. }).annotateMerge(
  121. OpenApi.annotations({
  122. identifier: "global.upgrade",
  123. summary: "Upgrade kirincode",
  124. description: "Upgrade kirincode to the specified version or latest if not specified.",
  125. }),
  126. ),
  127. )
  128. .annotateMerge(OpenApi.annotations({ title: "global", description: "Global server routes." })),
  129. )