t3code-cli 0.1.2 → 0.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.
@@ -1,4 +1,4 @@
1
- import type { ServerProvider } from "./schema.ts";
1
+ import type { ServerProvider } from "@t3tools/contracts";
2
2
 
3
3
  export function isSelectableProvider(provider: ServerProvider) {
4
4
  return provider.status === "ready" && provider.models.length > 0;
@@ -1,19 +1,13 @@
1
- import * as Schema from "effect/Schema";
2
-
3
1
  import {
4
- type ThreadDetail,
5
- type ThreadEvent,
6
- type ThreadMessage,
7
- type ThreadShell,
8
- ThreadMessageSchema,
9
- ThreadMessageSentEventSchema,
10
- ThreadSessionSetEventSchema,
11
- } from "./schema.ts";
12
-
13
- const isThreadMessageSentEvent = Schema.is(ThreadMessageSentEventSchema);
14
- const isThreadSessionSetEvent = Schema.is(ThreadSessionSetEventSchema);
2
+ OrchestrationMessage,
3
+ type OrchestrationEvent,
4
+ type OrchestrationMessage as OrchestrationMessageType,
5
+ type OrchestrationThread,
6
+ type OrchestrationThreadShell,
7
+ } from "@t3tools/contracts";
8
+ import * as Schema from "effect/Schema";
15
9
 
16
- export function isThreadActive(thread: ThreadShell | ThreadDetail) {
10
+ export function isThreadActive(thread: OrchestrationThreadShell | OrchestrationThread) {
17
11
  return (
18
12
  thread.session?.status === "starting" ||
19
13
  thread.session?.status === "running" ||
@@ -22,18 +16,18 @@ export function isThreadActive(thread: ThreadShell | ThreadDetail) {
22
16
  );
23
17
  }
24
18
 
25
- export function threadStatus(thread: ThreadShell | ThreadDetail) {
19
+ export function threadStatus(thread: OrchestrationThreadShell | OrchestrationThread) {
26
20
  if (isPendingStart(thread)) {
27
21
  return "pending";
28
22
  }
29
23
  return thread.session?.status ?? thread.latestTurn?.state ?? "unknown";
30
24
  }
31
25
 
32
- export function latestAssistantMessage(thread: ThreadDetail) {
26
+ export function latestAssistantMessage(thread: OrchestrationThread) {
33
27
  return thread.messages.toReversed().find((message) => message.role === "assistant");
34
28
  }
35
29
 
36
- export function isThreadCompleteEnough(thread: ThreadDetail) {
30
+ export function isThreadCompleteEnough(thread: OrchestrationThread) {
37
31
  if (thread.session?.status === "error" || thread.session?.status === "interrupted") {
38
32
  return true;
39
33
  }
@@ -45,16 +39,16 @@ export function isThreadCompleteEnough(thread: ThreadDetail) {
45
39
  }
46
40
 
47
41
  export function applyThreadEvent(
48
- current: ThreadDetail,
49
- event: ThreadEvent,
50
- messages: Map<string, ThreadMessage>,
42
+ current: OrchestrationThread,
43
+ event: OrchestrationEvent,
44
+ messages: Map<string, OrchestrationMessageType>,
51
45
  ) {
52
46
  const message = messageFromEvent(event, messages);
53
47
  if (message !== null) {
54
48
  messages.set(messageKey(message), message);
55
49
  return { ...current, messages: [...messages.values()] };
56
50
  }
57
- if (isThreadSessionSetEvent(event)) {
51
+ if (event.type === "thread.session-set") {
58
52
  return {
59
53
  ...current,
60
54
  session: event.payload.session,
@@ -64,32 +58,32 @@ export function applyThreadEvent(
64
58
  }
65
59
 
66
60
  export function messageFromEvent(
67
- event: ThreadEvent,
68
- existingMessages: Map<string, ThreadMessage> = new Map(),
69
- ): ThreadMessage | null {
70
- if (!isThreadMessageSentEvent(event)) {
61
+ event: OrchestrationEvent,
62
+ existingMessages: Map<string, OrchestrationMessageType> = new Map(),
63
+ ): OrchestrationMessageType | null {
64
+ if (event.type !== "thread.message-sent") {
71
65
  return null;
72
66
  }
73
67
  const payload = event.payload;
74
68
  const id = payload.messageId;
75
69
  const previous = existingMessages.get(id);
76
70
  const text = payload.text;
77
- return Schema.decodeUnknownSync(ThreadMessageSchema)({
71
+ return Schema.decodeUnknownSync(OrchestrationMessage)({
78
72
  id,
79
73
  role: payload.role,
80
74
  text: text.length > 0 || previous === undefined ? text : previous.text,
81
75
  turnId: payload.turnId,
82
- ...(payload.streaming !== undefined ? { streaming: payload.streaming } : {}),
76
+ streaming: payload.streaming,
83
77
  createdAt: payload.createdAt,
84
78
  updatedAt: payload.updatedAt,
85
79
  });
86
80
  }
87
81
 
88
- export function messageKey(message: ThreadMessage) {
89
- return message.id ?? message.messageId ?? `${message.role}:${message.createdAt}`;
82
+ export function messageKey(message: OrchestrationMessageType) {
83
+ return message.id;
90
84
  }
91
85
 
92
- function isPendingStart(thread: ThreadShell | ThreadDetail) {
86
+ function isPendingStart(thread: OrchestrationThreadShell | OrchestrationThread) {
93
87
  if (thread.session !== null || thread.latestTurn !== null || !("messages" in thread)) {
94
88
  return false;
95
89
  }
package/src/index.ts CHANGED
@@ -7,12 +7,12 @@ export type {
7
7
  } from "./application/service.ts";
8
8
  export type { ApplicationError } from "./application/error.ts";
9
9
  export type {
10
- ProjectShell,
10
+ OrchestrationMessage,
11
+ OrchestrationProjectShell,
12
+ OrchestrationShellSnapshot,
13
+ OrchestrationThread,
14
+ OrchestrationThreadShell,
11
15
  ServerProvider,
12
- ShellSnapshot,
13
- ThreadDetail,
14
- ThreadMessage,
15
- ThreadShell,
16
- } from "./domain/schema.ts";
16
+ } from "@t3tools/contracts";
17
17
  export { NodeEnvironmentLive } from "./environment/layer.ts";
18
18
  export { AppLayer, AuthAppLayer } from "./runtime.ts";
@@ -4,34 +4,35 @@ import * as Option from "effect/Option";
4
4
  import * as Schedule from "effect/Schedule";
5
5
  import * as Sink from "effect/Sink";
6
6
  import * as Stream from "effect/Stream";
7
- import { RpcClientError } from "effect/unstable/rpc";
8
-
9
- import { type ClientOrchestrationCommand } from "../domain/command-schema.ts";
10
7
  import {
11
8
  ORCHESTRATION_WS_METHODS,
12
- type ShellStreamItem,
13
- type ThreadStreamItem,
9
+ ThreadId,
14
10
  WS_METHODS,
15
- } from "../protocol/schema.ts";
11
+ type ClientOrchestrationCommand,
12
+ type OrchestrationShellStreamItem,
13
+ type OrchestrationThreadStreamItem,
14
+ } from "@t3tools/contracts";
15
+ import { RpcClientError } from "effect/unstable/rpc";
16
+
16
17
  import { RpcError } from "../rpc/error.ts";
17
18
  import { T3Rpc, type WsClient } from "../rpc/service.ts";
19
+ import type { CliRpcRequestError } from "../rpc/ws-group.ts";
18
20
  import { T3Orchestration, type OpenThread } from "./service.ts";
19
21
 
20
- type ReconnectableRpcError = RpcClientError.RpcClientError | RpcError;
22
+ type RpcRequestError = RpcClientError.RpcClientError | CliRpcRequestError;
21
23
 
22
24
  const rpcRetrySchedule = Schedule.exponential("100 millis").pipe(
23
25
  Schedule.take(4),
24
26
  Schedule.collectWhile(
25
- (metadata: Schedule.Metadata<unknown, ReconnectableRpcError>) =>
26
- metadata.input instanceof RpcClientError.RpcClientError,
27
+ (metadata: Schedule.Metadata) => metadata.input instanceof RpcClientError.RpcClientError,
27
28
  ),
28
29
  );
29
30
 
30
31
  function runRpc<A>(
31
32
  rpc: T3Rpc["Service"],
32
33
  method: string,
33
- f: (client: WsClient) => Effect.Effect<A, ReconnectableRpcError>,
34
- ) {
34
+ f: (client: WsClient) => Effect.Effect<A, RpcRequestError>,
35
+ ): Effect.Effect<A, RpcError> {
35
36
  return Effect.gen(function* () {
36
37
  const client = yield* rpc.getClient;
37
38
  return yield* f(client);
@@ -41,15 +42,13 @@ function runRpc<A>(
41
42
  ),
42
43
  Effect.retry(rpcRetrySchedule),
43
44
  Effect.catchTags({
44
- RpcClientError: (error) =>
45
- Effect.fail(
46
- new RpcError({
47
- message: error.message,
48
- method,
49
- cause: error,
50
- }),
51
- ),
52
45
  RpcError: (error) => Effect.fail(error),
46
+ EnvironmentAuthorizationError: (error) => Effect.fail(toRpcRequestError(error, method)),
47
+ RpcClientError: (error) => Effect.fail(toRpcRequestError(error, method)),
48
+ KeybindingsConfigParseError: (error) => Effect.fail(toRpcRequestError(error, method)),
49
+ OrchestrationDispatchCommandError: (error) => Effect.fail(toRpcRequestError(error, method)),
50
+ OrchestrationGetSnapshotError: (error) => Effect.fail(toRpcRequestError(error, method)),
51
+ ServerSettingsError: (error) => Effect.fail(toRpcRequestError(error, method)),
53
52
  }),
54
53
  );
55
54
  }
@@ -57,23 +56,21 @@ function runRpc<A>(
57
56
  function subscribeRpc<A>(
58
57
  rpc: T3Rpc["Service"],
59
58
  method: string,
60
- f: (client: WsClient) => Stream.Stream<A, ReconnectableRpcError>,
61
- ) {
59
+ f: (client: WsClient) => Stream.Stream<A, RpcRequestError>,
60
+ ): Stream.Stream<A, RpcError> {
62
61
  return Stream.unwrap(Effect.map(rpc.getClient, f)).pipe(
63
62
  Stream.tapError((error) =>
64
63
  error instanceof RpcClientError.RpcClientError ? rpc.disconnect : Effect.void,
65
64
  ),
66
65
  Stream.retry(rpcRetrySchedule),
67
66
  Stream.catchTags({
68
- RpcClientError: (error) =>
69
- Stream.fail(
70
- new RpcError({
71
- message: error.message,
72
- method,
73
- cause: error,
74
- }),
75
- ),
76
67
  RpcError: (error) => Stream.fail(error),
68
+ EnvironmentAuthorizationError: (error) => Stream.fail(toRpcRequestError(error, method)),
69
+ RpcClientError: (error) => Stream.fail(toRpcRequestError(error, method)),
70
+ KeybindingsConfigParseError: (error) => Stream.fail(toRpcRequestError(error, method)),
71
+ OrchestrationDispatchCommandError: (error) => Stream.fail(toRpcRequestError(error, method)),
72
+ OrchestrationGetSnapshotError: (error) => Stream.fail(toRpcRequestError(error, method)),
73
+ ServerSettingsError: (error) => Stream.fail(toRpcRequestError(error, method)),
77
74
  }),
78
75
  );
79
76
  }
@@ -83,20 +80,8 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
83
80
  const dispatch = Effect.fn("T3OrchestrationLive.dispatch")(function* (
84
81
  command: ClientOrchestrationCommand,
85
82
  ) {
86
- const client = yield* rpc.getClient;
87
- return yield* client[ORCHESTRATION_WS_METHODS.dispatchCommand](command).pipe(
88
- Effect.tapErrorTag("RpcClientError", () => rpc.disconnect),
89
- Effect.catchTags({
90
- RpcClientError: (error) =>
91
- Effect.fail(
92
- new RpcError({
93
- message: error.message,
94
- method: ORCHESTRATION_WS_METHODS.dispatchCommand,
95
- cause: error,
96
- }),
97
- ),
98
- RpcError: (error) => Effect.fail(error),
99
- }),
83
+ return yield* runRpc(rpc, ORCHESTRATION_WS_METHODS.dispatchCommand, (client) =>
84
+ client[ORCHESTRATION_WS_METHODS.dispatchCommand](command),
100
85
  );
101
86
  });
102
87
  const getServerConfig = Effect.fn("T3OrchestrationLive.getServerConfig")(function* () {
@@ -126,7 +111,7 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
126
111
  ) {
127
112
  const item = yield* Stream.runHead(
128
113
  subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeThread, (client) =>
129
- client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId }),
114
+ client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId: ThreadId.make(threadId) }),
130
115
  ),
131
116
  );
132
117
  const value = Option.getOrUndefined(item);
@@ -144,17 +129,17 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
144
129
  subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeShell, (client) =>
145
130
  client[ORCHESTRATION_WS_METHODS.subscribeShell]({}),
146
131
  ).pipe(
147
- Stream.map((item: ShellStreamItem) =>
132
+ Stream.map((item: OrchestrationShellStreamItem) =>
148
133
  item.kind === "snapshot" ? item.snapshot.snapshotSequence : item.sequence,
149
134
  ),
150
135
  );
151
136
  const watchThreadItems = (threadId: string) =>
152
137
  subscribeRpc(rpc, ORCHESTRATION_WS_METHODS.subscribeThread, (client) =>
153
- client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId }),
138
+ client[ORCHESTRATION_WS_METHODS.subscribeThread]({ threadId: ThreadId.make(threadId) }),
154
139
  );
155
140
  const openThread = Effect.fn("T3OrchestrationLive.openThread")(function* (threadId: string) {
156
141
  return yield* watchThreadItems(threadId).pipe(
157
- Stream.peel(Sink.head<ThreadStreamItem>()),
142
+ Stream.peel(Sink.head<OrchestrationThreadStreamItem>()),
158
143
  Effect.flatMap(([item, rest]) => {
159
144
  const value = Option.getOrUndefined(item);
160
145
  if (value === undefined || value.kind !== "snapshot") {
@@ -169,7 +154,7 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
169
154
  snapshot: value.snapshot.thread,
170
155
  events: rest.pipe(
171
156
  Stream.filter(
172
- (next): next is Extract<ThreadStreamItem, { readonly kind: "event" }> =>
157
+ (next): next is Extract<OrchestrationThreadStreamItem, { readonly kind: "event" }> =>
173
158
  next.kind === "event",
174
159
  ),
175
160
  Stream.map((next) => next.event),
@@ -191,3 +176,11 @@ export const makeT3Orchestration = Effect.fn("makeT3Orchestration")(function* ()
191
176
  });
192
177
 
193
178
  export const T3OrchestrationLive = Layer.effect(T3Orchestration, makeT3Orchestration());
179
+
180
+ function toRpcRequestError(error: RpcRequestError, method: string) {
181
+ return new RpcError({
182
+ message: error.message,
183
+ method,
184
+ cause: error,
185
+ });
186
+ }
@@ -2,33 +2,42 @@ import * as Context from "effect/Context";
2
2
  import type * as Effect from "effect/Effect";
3
3
  import type * as Scope from "effect/Scope";
4
4
  import type * as Stream from "effect/Stream";
5
+ import type {
6
+ ClientOrchestrationCommand,
7
+ DispatchResult,
8
+ OrchestrationEvent,
9
+ OrchestrationShellSnapshot,
10
+ OrchestrationThread,
11
+ OrchestrationThreadStreamItem,
12
+ ServerProviders,
13
+ } from "@t3tools/contracts";
5
14
 
6
- import type { ClientOrchestrationCommand, DispatchResult } from "../domain/command-schema.ts";
7
- import type { ServerConfig, ShellSnapshot, ThreadDetail, ThreadEvent } from "../domain/schema.ts";
8
15
  import type { RpcError } from "../rpc/error.ts";
9
16
 
10
17
  export type OrchestrationError = RpcError;
11
18
 
12
19
  export type OpenThread = {
13
- readonly snapshot: ThreadDetail;
14
- readonly events: Stream.Stream<ThreadEvent, OrchestrationError>;
20
+ readonly snapshot: OrchestrationThread;
21
+ readonly events: Stream.Stream<OrchestrationEvent, OrchestrationError>;
15
22
  };
16
23
 
17
- export type ThreadStreamItem =
18
- | { readonly kind: "snapshot"; readonly snapshot: { readonly thread: ThreadDetail } }
19
- | { readonly kind: "event"; readonly event: ThreadEvent };
24
+ export type ServerConfigForCli = {
25
+ readonly providers: ServerProviders;
26
+ };
20
27
 
21
28
  export type Orchestration = {
22
29
  readonly dispatch: (
23
30
  command: ClientOrchestrationCommand,
24
31
  ) => Effect.Effect<DispatchResult, OrchestrationError>;
25
- readonly getServerConfig: () => Effect.Effect<ServerConfig, OrchestrationError>;
26
- readonly getShellSnapshot: () => Effect.Effect<ShellSnapshot, OrchestrationError>;
27
- readonly getThreadSnapshot: (threadId: string) => Effect.Effect<ThreadDetail, OrchestrationError>;
32
+ readonly getServerConfig: () => Effect.Effect<ServerConfigForCli, OrchestrationError>;
33
+ readonly getShellSnapshot: () => Effect.Effect<OrchestrationShellSnapshot, OrchestrationError>;
34
+ readonly getThreadSnapshot: (
35
+ threadId: string,
36
+ ) => Effect.Effect<OrchestrationThread, OrchestrationError>;
28
37
  readonly watchShellSequence: () => Stream.Stream<number, OrchestrationError, Scope.Scope>;
29
38
  readonly watchThreadItems: (
30
39
  threadId: string,
31
- ) => Stream.Stream<ThreadStreamItem, OrchestrationError, Scope.Scope>;
40
+ ) => Stream.Stream<OrchestrationThreadStreamItem, OrchestrationError, Scope.Scope>;
32
41
  readonly openThread: (
33
42
  threadId: string,
34
43
  ) => Effect.Effect<OpenThread, OrchestrationError, Scope.Scope>;
package/src/rpc/error.ts CHANGED
@@ -1,4 +1,11 @@
1
1
  import * as Schema from "effect/Schema";
2
+ import {
3
+ EnvironmentAuthorizationError,
4
+ KeybindingsConfigError,
5
+ OrchestrationDispatchCommandError,
6
+ OrchestrationGetSnapshotError,
7
+ ServerSettingsError,
8
+ } from "@t3tools/contracts";
2
9
  import { HttpClientError } from "effect/unstable/http";
3
10
  import { RpcClientError } from "effect/unstable/rpc";
4
11
 
@@ -12,6 +19,11 @@ import { ConfigError, UrlError } from "../config/error.ts";
12
19
 
13
20
  const RpcErrorCauseSchema = Schema.Union([
14
21
  RpcClientError.RpcClientError,
22
+ EnvironmentAuthorizationError,
23
+ KeybindingsConfigError,
24
+ OrchestrationDispatchCommandError,
25
+ OrchestrationGetSnapshotError,
26
+ ServerSettingsError,
15
27
  AuthConfigError,
16
28
  AuthLocalError,
17
29
  AuthPairingUrlError,
package/src/rpc/layer.ts CHANGED
@@ -13,12 +13,12 @@ import * as Socket from "effect/unstable/socket/Socket";
13
13
 
14
14
  import { T3Auth } from "../auth/service.ts";
15
15
  import { T3Config } from "../config/service.ts";
16
- import { toWebSocketBaseUrl } from "../config/url.ts";
17
- import { WsRpcGroup } from "../protocol/schema.ts";
16
+ import { toWebSocketEndpointUrl } from "../config/url.ts";
17
+ import { CliWsRpcGroup } from "./ws-group.ts";
18
18
  import { RpcError } from "./error.ts";
19
19
  import { T3Rpc, type WsClient } from "./service.ts";
20
20
 
21
- const makeClient = RpcClient.make(WsRpcGroup);
21
+ const makeClient = RpcClient.make(CliWsRpcGroup);
22
22
  const connectionRetrySchedule = Schedule.exponential("100 millis").pipe(Schedule.take(4));
23
23
 
24
24
  type Connection = {
@@ -77,7 +77,7 @@ const makeWsUrl = Effect.fn("makeWsUrl")(function* (input: {
77
77
  }) {
78
78
  const resolved = yield* input.config.resolve();
79
79
  const wsToken = yield* input.auth.issueWebSocketToken();
80
- const wsUrl = yield* toWebSocketBaseUrl(resolved.url);
80
+ const wsUrl = yield* toWebSocketEndpointUrl(resolved.url, "/ws");
81
81
  const request = HttpClientRequest.get(wsUrl).pipe(
82
82
  HttpClientRequest.setUrlParam("wsToken", wsToken.token),
83
83
  );
@@ -1,11 +1,10 @@
1
1
  import * as Context from "effect/Context";
2
2
  import type * as Effect from "effect/Effect";
3
3
  import type { RpcClient, RpcClientError } from "effect/unstable/rpc";
4
-
5
- import type { WsRpcGroup } from "../protocol/schema.ts";
4
+ import type { CliWsRpcGroup } from "./ws-group.ts";
6
5
  import type { RpcError } from "./error.ts";
7
6
 
8
- export type WsClient = RpcClient.FromGroup<typeof WsRpcGroup, RpcClientError.RpcClientError>;
7
+ export type WsClient = RpcClient.FromGroup<typeof CliWsRpcGroup, RpcClientError.RpcClientError>;
9
8
 
10
9
  export type T3RpcService = {
11
10
  readonly getClient: Effect.Effect<WsClient, RpcError>;
@@ -0,0 +1,43 @@
1
+ import {
2
+ EnvironmentAuthorizationError,
3
+ KeybindingsConfigError,
4
+ OrchestrationDispatchCommandError,
5
+ OrchestrationGetSnapshotError,
6
+ ServerConfig,
7
+ ServerProviders,
8
+ ServerSettingsError,
9
+ WS_METHODS,
10
+ WsOrchestrationDispatchCommandRpc,
11
+ WsOrchestrationSubscribeShellRpc,
12
+ WsOrchestrationSubscribeThreadRpc,
13
+ } from "@t3tools/contracts";
14
+ import * as Schema from "effect/Schema";
15
+ import { Rpc, RpcGroup } from "effect/unstable/rpc";
16
+
17
+ export const FallbackServerConfig = Schema.Struct({
18
+ providers: ServerProviders,
19
+ });
20
+ export type FallbackServerConfig = typeof FallbackServerConfig.Type;
21
+
22
+ export const CliServerConfig = Schema.Union([ServerConfig, FallbackServerConfig]);
23
+ export type CliServerConfig = typeof CliServerConfig.Type;
24
+
25
+ export const WsServerGetConfigRpc = Rpc.make(WS_METHODS.serverGetConfig, {
26
+ payload: Schema.Struct({}),
27
+ success: CliServerConfig,
28
+ error: Schema.Union([KeybindingsConfigError, ServerSettingsError, EnvironmentAuthorizationError]),
29
+ });
30
+
31
+ export const CliWsRpcGroup = RpcGroup.make(
32
+ WsOrchestrationDispatchCommandRpc,
33
+ WsOrchestrationSubscribeShellRpc,
34
+ WsOrchestrationSubscribeThreadRpc,
35
+ WsServerGetConfigRpc,
36
+ );
37
+
38
+ export type CliRpcRequestError =
39
+ | EnvironmentAuthorizationError
40
+ | KeybindingsConfigError
41
+ | OrchestrationDispatchCommandError
42
+ | OrchestrationGetSnapshotError
43
+ | ServerSettingsError;
@@ -1,82 +0,0 @@
1
- import * as Schema from "effect/Schema";
2
-
3
- import { ModelSelectionSchema } from "./schema.ts";
4
-
5
- export const DispatchResultSchema = Schema.Struct({
6
- sequence: Schema.Number,
7
- });
8
- export type DispatchResult = typeof DispatchResultSchema.Type;
9
-
10
- export const ProjectCreateCommandSchema = Schema.Struct({
11
- type: Schema.Literal("project.create"),
12
- commandId: Schema.String,
13
- projectId: Schema.String,
14
- title: Schema.String,
15
- workspaceRoot: Schema.String,
16
- createdAt: Schema.String,
17
- });
18
- export type ProjectCreateCommand = typeof ProjectCreateCommandSchema.Type;
19
-
20
- export const ThreadCreateCommandSchema = Schema.Struct({
21
- type: Schema.Literal("thread.create"),
22
- commandId: Schema.String,
23
- threadId: Schema.String,
24
- projectId: Schema.String,
25
- title: Schema.String,
26
- modelSelection: ModelSelectionSchema,
27
- runtimeMode: Schema.Literal("full-access"),
28
- interactionMode: Schema.Literal("default"),
29
- branch: Schema.Null,
30
- worktreePath: Schema.NullOr(Schema.String),
31
- createdAt: Schema.String,
32
- });
33
- export type ThreadCreateCommand = typeof ThreadCreateCommandSchema.Type;
34
-
35
- export const ThreadTurnStartCommandSchema = Schema.Struct({
36
- type: Schema.Literal("thread.turn.start"),
37
- commandId: Schema.String,
38
- threadId: Schema.String,
39
- message: Schema.Struct({
40
- messageId: Schema.String,
41
- role: Schema.Literal("user"),
42
- text: Schema.String,
43
- attachments: Schema.Array(Schema.Never),
44
- }),
45
- modelSelection: Schema.optionalKey(ModelSelectionSchema),
46
- titleSeed: Schema.optionalKey(Schema.String),
47
- runtimeMode: Schema.Literal("full-access"),
48
- interactionMode: Schema.Literal("default"),
49
- bootstrap: Schema.optionalKey(
50
- Schema.Struct({
51
- createThread: Schema.optionalKey(
52
- Schema.Struct({
53
- projectId: Schema.String,
54
- title: Schema.String,
55
- modelSelection: ModelSelectionSchema,
56
- runtimeMode: Schema.Literal("full-access"),
57
- interactionMode: Schema.Literal("default"),
58
- branch: Schema.Null,
59
- worktreePath: Schema.NullOr(Schema.String),
60
- createdAt: Schema.String,
61
- }),
62
- ),
63
- }),
64
- ),
65
- createdAt: Schema.String,
66
- });
67
- export type ThreadTurnStartCommand = typeof ThreadTurnStartCommandSchema.Type;
68
-
69
- export const ThreadArchiveCommandSchema = Schema.Struct({
70
- type: Schema.Literal("thread.archive"),
71
- commandId: Schema.String,
72
- threadId: Schema.String,
73
- });
74
- export type ThreadArchiveCommand = typeof ThreadArchiveCommandSchema.Type;
75
-
76
- export const ClientOrchestrationCommandSchema = Schema.Union([
77
- ProjectCreateCommandSchema,
78
- ThreadArchiveCommandSchema,
79
- ThreadCreateCommandSchema,
80
- ThreadTurnStartCommandSchema,
81
- ]);
82
- export type ClientOrchestrationCommand = typeof ClientOrchestrationCommandSchema.Type;