@krak-stack/registry 0.1.2 → 0.1.4
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/README.md +17 -1
- package/dist/components/ui/alert.d.ts +10 -0
- package/dist/components/ui/app-brand.js +20 -20
- package/dist/components/ui/bubble.d.ts +16 -0
- package/dist/components/ui/code-block.js +38 -38
- package/dist/components/ui/collapsible.d.ts +5 -0
- package/dist/components/ui/copy-button.js +16 -16
- package/dist/components/ui/data-table.js +687 -687
- package/dist/components/ui/editing-locale-switcher.js +54 -54
- package/dist/components/ui/effect-form.js +490 -490
- package/dist/components/ui/empty.d.ts +11 -0
- package/dist/components/ui/file-picker.js +96 -96
- package/dist/components/ui/form.js +418 -418
- package/dist/components/ui/google-map.js +27 -27
- package/dist/components/ui/icon-input.js +93 -93
- package/dist/components/ui/loading.js +5 -5
- package/dist/components/ui/locale-switcher.js +48 -48
- package/dist/components/ui/marker.d.ts +10 -0
- package/dist/components/ui/message-scroller.d.ts +10 -0
- package/dist/components/ui/message.d.ts +10 -0
- package/dist/components/ui/pagination.js +92 -92
- package/dist/components/ui/search-menu.js +93 -93
- package/dist/components/ui/sidebar-layout.js +156 -156
- package/dist/components/ui/stats-card.js +28 -28
- package/dist/components/ui/theme-switcher.js +64 -64
- package/dist/components/ui/virtualized-combobox.js +66 -66
- package/dist/lib/docs-ai.d.ts +136 -0
- package/dist/lib/docs-ai.js +310 -0
- package/dist/lib/docs-core.d.ts +681 -0
- package/dist/lib/docs-core.js +2571 -0
- package/dist/lib/httpapi-ai.d.ts +54 -0
- package/dist/lib/httpapi-ai.js +361 -0
- package/dist/lib/httpapi-cli.d.ts +22 -0
- package/dist/lib/httpapi-cli.js +412 -0
- package/dist/lib/httpapi-client.d.ts +20 -0
- package/dist/lib/httpapi-client.js +50 -0
- package/dist/lib/httpapi-helpers.d.ts +105 -0
- package/dist/lib/httpapi-helpers.js +237 -0
- package/dist/lib/httpapi-mcp.d.ts +20 -0
- package/dist/lib/httpapi-mcp.js +366 -0
- package/dist/lib/query.js +128 -0
- package/dist/services/agent/client/atom.d.ts +56 -0
- package/dist/services/agent/client/index.d.ts +2 -0
- package/dist/services/agent/client/index.js +2239 -0
- package/dist/services/agent/client/widget.d.ts +52 -0
- package/dist/services/agent/index.d.ts +111 -0
- package/dist/services/agent/index.js +190 -0
- package/dist/services/agent/schema.d.ts +161 -0
- package/dist/services/agent/schema.js +135 -0
- package/package.json +59 -3
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { AgentState, AgentSubmitAction } from "./atom.js";
|
|
3
|
+
import type { AgentReference } from "../schema.js";
|
|
4
|
+
export type AgentWidgetReference<Resource> = AgentReference<Resource> & {
|
|
5
|
+
readonly icon?: ReactNode;
|
|
6
|
+
readonly key: string;
|
|
7
|
+
};
|
|
8
|
+
export type AgentWidgetMessages = {
|
|
9
|
+
approve: string;
|
|
10
|
+
approvalDestructive: string;
|
|
11
|
+
approvalDestructiveLabel: string;
|
|
12
|
+
approvalRequired: string;
|
|
13
|
+
cancel: string;
|
|
14
|
+
close: string;
|
|
15
|
+
copied: string;
|
|
16
|
+
copy: string;
|
|
17
|
+
description: string;
|
|
18
|
+
errorInvalidRequest: string;
|
|
19
|
+
errorRoundLimit: string;
|
|
20
|
+
errorStreamFailed: string;
|
|
21
|
+
errorUnavailable: string;
|
|
22
|
+
maximize: string;
|
|
23
|
+
minimize: string;
|
|
24
|
+
noReferences: string;
|
|
25
|
+
open: string;
|
|
26
|
+
placeholder: string;
|
|
27
|
+
removeContext: string;
|
|
28
|
+
references: string;
|
|
29
|
+
restore: string;
|
|
30
|
+
scrollLatest: string;
|
|
31
|
+
send: string;
|
|
32
|
+
stop: string;
|
|
33
|
+
title: string;
|
|
34
|
+
toolDenied: string;
|
|
35
|
+
toolFailed: string;
|
|
36
|
+
toolRunning: string;
|
|
37
|
+
toolWorked: (seconds: number) => string;
|
|
38
|
+
viewLess: string;
|
|
39
|
+
viewMore: string;
|
|
40
|
+
welcome: string;
|
|
41
|
+
};
|
|
42
|
+
export declare const agentWidgetMessages: (locale?: "en" | "fr", overrides?: Partial<AgentWidgetMessages>) => AgentWidgetMessages;
|
|
43
|
+
export declare function AgentWidget<Resource = never>({ availableReferences, context, messages: messageOverrides, onInterrupt, onRemoveContext, onReset, onSubmit, state, }: {
|
|
44
|
+
readonly availableReferences?: ReadonlyArray<AgentWidgetReference<Resource>>;
|
|
45
|
+
readonly context?: AgentWidgetReference<Resource>;
|
|
46
|
+
readonly messages?: Partial<AgentWidgetMessages>;
|
|
47
|
+
readonly onInterrupt: () => void;
|
|
48
|
+
readonly onRemoveContext?: () => void;
|
|
49
|
+
readonly onReset: () => void;
|
|
50
|
+
readonly onSubmit: (action: AgentSubmitAction<Resource>) => void;
|
|
51
|
+
readonly state: AgentState<Resource>;
|
|
52
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Stream } from "effect";
|
|
2
|
+
import { LanguageModel, Tool, Toolkit } from "effect/unstable/ai";
|
|
3
|
+
import type { AgentAction } from "./schema.js";
|
|
4
|
+
export type AgentStreamOptions<Tools extends Record<string, Tool.Any>> = {
|
|
5
|
+
readonly action: AgentAction;
|
|
6
|
+
readonly history?: string;
|
|
7
|
+
readonly systemPrompt: string;
|
|
8
|
+
readonly toolkit: Toolkit.WithHandler<Tools>;
|
|
9
|
+
};
|
|
10
|
+
declare const AgentHistoryError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
11
|
+
readonly _tag: "AgentHistoryError";
|
|
12
|
+
} & Readonly<A>;
|
|
13
|
+
declare class AgentHistoryError extends AgentHistoryError_base {
|
|
14
|
+
}
|
|
15
|
+
declare const AgentService_base: Context.ServiceClass<AgentService, "AgentService", {
|
|
16
|
+
stream: <Tools extends Record<string, Tool.Any>>(args_0: AgentStreamOptions<Tools>) => Effect.Effect<Stream.Stream<import("effect/Schema").Struct.ReadonlySide<{
|
|
17
|
+
readonly type: import("effect/Schema").Literal<"message-start">;
|
|
18
|
+
readonly messageId: import("effect/Schema").String;
|
|
19
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
20
|
+
readonly type: import("effect/Schema").Literal<"text-delta">;
|
|
21
|
+
readonly messageId: import("effect/Schema").String;
|
|
22
|
+
readonly delta: import("effect/Schema").String;
|
|
23
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
24
|
+
readonly type: import("effect/Schema").Literal<"tool-call">;
|
|
25
|
+
readonly messageId: import("effect/Schema").String;
|
|
26
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
27
|
+
readonly name: import("effect/Schema").String;
|
|
28
|
+
readonly input: import("effect/Schema").Unknown;
|
|
29
|
+
readonly metadata: import("effect/Schema").Struct<{
|
|
30
|
+
readonly title: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
31
|
+
readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
32
|
+
readonly destructive: import("effect/Schema").Boolean;
|
|
33
|
+
}>;
|
|
34
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
35
|
+
readonly type: import("effect/Schema").Literal<"tool-result">;
|
|
36
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
37
|
+
readonly name: import("effect/Schema").String;
|
|
38
|
+
readonly isFailure: import("effect/Schema").Boolean;
|
|
39
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
40
|
+
readonly type: import("effect/Schema").Literal<"approval-required">;
|
|
41
|
+
readonly approvalId: import("effect/Schema").String;
|
|
42
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
43
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
44
|
+
readonly type: import("effect/Schema").Literal<"history">;
|
|
45
|
+
readonly value: import("effect/Schema").String;
|
|
46
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
47
|
+
readonly type: import("effect/Schema").Literal<"finish">;
|
|
48
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
49
|
+
readonly type: import("effect/Schema").Literal<"error">;
|
|
50
|
+
readonly code: import("effect/Schema").Literals<readonly ["unavailable", "invalid-request", "round-limit", "stream-failed"]>;
|
|
51
|
+
}, "Type"> | {
|
|
52
|
+
type: "history";
|
|
53
|
+
value: string;
|
|
54
|
+
} | {
|
|
55
|
+
type: "error";
|
|
56
|
+
code: "stream-failed";
|
|
57
|
+
} | {
|
|
58
|
+
type: "finish";
|
|
59
|
+
}, never, Exclude<Tool.HandlerServices<Tools[keyof Tools]>, LanguageModel.LanguageModel> | Exclude<Tool.ResultDecodingServices<Tools[keyof Tools]>, LanguageModel.LanguageModel>>, AgentHistoryError | import("effect/SchemaError").SchemaError, LanguageModel.LanguageModel>;
|
|
60
|
+
}> & {
|
|
61
|
+
readonly make: Effect.Effect<{
|
|
62
|
+
stream: <Tools extends Record<string, Tool.Any>>(args_0: AgentStreamOptions<Tools>) => Effect.Effect<Stream.Stream<import("effect/Schema").Struct.ReadonlySide<{
|
|
63
|
+
readonly type: import("effect/Schema").Literal<"message-start">;
|
|
64
|
+
readonly messageId: import("effect/Schema").String;
|
|
65
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
66
|
+
readonly type: import("effect/Schema").Literal<"text-delta">;
|
|
67
|
+
readonly messageId: import("effect/Schema").String;
|
|
68
|
+
readonly delta: import("effect/Schema").String;
|
|
69
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
70
|
+
readonly type: import("effect/Schema").Literal<"tool-call">;
|
|
71
|
+
readonly messageId: import("effect/Schema").String;
|
|
72
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
73
|
+
readonly name: import("effect/Schema").String;
|
|
74
|
+
readonly input: import("effect/Schema").Unknown;
|
|
75
|
+
readonly metadata: import("effect/Schema").Struct<{
|
|
76
|
+
readonly title: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
77
|
+
readonly description: import("effect/Schema").optional<import("effect/Schema").String>;
|
|
78
|
+
readonly destructive: import("effect/Schema").Boolean;
|
|
79
|
+
}>;
|
|
80
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
81
|
+
readonly type: import("effect/Schema").Literal<"tool-result">;
|
|
82
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
83
|
+
readonly name: import("effect/Schema").String;
|
|
84
|
+
readonly isFailure: import("effect/Schema").Boolean;
|
|
85
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
86
|
+
readonly type: import("effect/Schema").Literal<"approval-required">;
|
|
87
|
+
readonly approvalId: import("effect/Schema").String;
|
|
88
|
+
readonly toolCallId: import("effect/Schema").String;
|
|
89
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
90
|
+
readonly type: import("effect/Schema").Literal<"history">;
|
|
91
|
+
readonly value: import("effect/Schema").String;
|
|
92
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
93
|
+
readonly type: import("effect/Schema").Literal<"finish">;
|
|
94
|
+
}, "Type"> | import("effect/Schema").Struct.ReadonlySide<{
|
|
95
|
+
readonly type: import("effect/Schema").Literal<"error">;
|
|
96
|
+
readonly code: import("effect/Schema").Literals<readonly ["unavailable", "invalid-request", "round-limit", "stream-failed"]>;
|
|
97
|
+
}, "Type"> | {
|
|
98
|
+
type: "history";
|
|
99
|
+
value: string;
|
|
100
|
+
} | {
|
|
101
|
+
type: "error";
|
|
102
|
+
code: "stream-failed";
|
|
103
|
+
} | {
|
|
104
|
+
type: "finish";
|
|
105
|
+
}, never, Exclude<Tool.HandlerServices<Tools[keyof Tools]>, LanguageModel.LanguageModel> | Exclude<Tool.ResultDecodingServices<Tools[keyof Tools]>, LanguageModel.LanguageModel>>, AgentHistoryError | import("effect/SchemaError").SchemaError, LanguageModel.LanguageModel>;
|
|
106
|
+
}, never, never>;
|
|
107
|
+
};
|
|
108
|
+
export declare class AgentService extends AgentService_base {
|
|
109
|
+
static readonly layer: Layer.Layer<AgentService, never, never>;
|
|
110
|
+
}
|
|
111
|
+
export {};
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// ../../src/services/agent/index.ts
|
|
2
|
+
import { Context, Data, Effect, Layer, Option, Ref, Stream } from "effect";
|
|
3
|
+
import {
|
|
4
|
+
Chat,
|
|
5
|
+
LanguageModel,
|
|
6
|
+
Prompt,
|
|
7
|
+
Tool
|
|
8
|
+
} from "effect/unstable/ai";
|
|
9
|
+
|
|
10
|
+
class AgentHistoryError extends Data.TaggedError("AgentHistoryError") {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class AgentService extends Context.Service()("AgentService", {
|
|
14
|
+
make: Effect.gen(function* () {
|
|
15
|
+
const streamErrorDetails = (error) => {
|
|
16
|
+
if (!error || typeof error !== "object") {
|
|
17
|
+
return { error: String(error) };
|
|
18
|
+
}
|
|
19
|
+
const message = Reflect.get(error, "message");
|
|
20
|
+
const reason = Reflect.get(error, "reason");
|
|
21
|
+
const status = Reflect.get(error, "status");
|
|
22
|
+
const tag = Reflect.get(error, "_tag");
|
|
23
|
+
return {
|
|
24
|
+
...typeof message === "string" ? { message } : {},
|
|
25
|
+
...typeof reason === "string" ? { reason } : {},
|
|
26
|
+
...typeof status === "number" ? { status } : {},
|
|
27
|
+
...typeof tag === "string" ? { tag } : {}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const eventsForPart = ({
|
|
31
|
+
messageId,
|
|
32
|
+
part,
|
|
33
|
+
toolkit
|
|
34
|
+
}) => {
|
|
35
|
+
switch (part.type) {
|
|
36
|
+
case "text-delta":
|
|
37
|
+
return [{ type: "text-delta", messageId, delta: part.delta }];
|
|
38
|
+
case "tool-call": {
|
|
39
|
+
const tool = toolkit.tools[part.name];
|
|
40
|
+
const title = tool ? Option.getOrUndefined(Context.getOption(tool.annotations, Tool.Title)) : undefined;
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
type: "tool-call",
|
|
44
|
+
messageId,
|
|
45
|
+
toolCallId: part.id,
|
|
46
|
+
name: part.name,
|
|
47
|
+
input: part.params,
|
|
48
|
+
metadata: {
|
|
49
|
+
...title ? { title } : {},
|
|
50
|
+
...tool?.description ? { description: tool.description } : {},
|
|
51
|
+
destructive: tool ? Context.get(tool.annotations, Tool.Destructive) : false
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
case "tool-result":
|
|
57
|
+
return [
|
|
58
|
+
{
|
|
59
|
+
type: "tool-result",
|
|
60
|
+
toolCallId: part.id,
|
|
61
|
+
name: part.name,
|
|
62
|
+
isFailure: part.isFailure
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
case "tool-approval-request":
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
type: "approval-required",
|
|
69
|
+
approvalId: part.approvalId,
|
|
70
|
+
toolCallId: part.toolCallId
|
|
71
|
+
}
|
|
72
|
+
];
|
|
73
|
+
case "error":
|
|
74
|
+
return [{ type: "error", code: "stream-failed" }];
|
|
75
|
+
default:
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const agentRounds = ({
|
|
80
|
+
conversation,
|
|
81
|
+
messageId,
|
|
82
|
+
prompt,
|
|
83
|
+
round,
|
|
84
|
+
toolkit
|
|
85
|
+
}) => Stream.suspend(() => {
|
|
86
|
+
let hasApproval = false;
|
|
87
|
+
const toolCallIds = new Set;
|
|
88
|
+
const toolResultIds = new Set;
|
|
89
|
+
const current = conversation.streamText({ prompt, toolkit }).pipe(Stream.tap((part) => Effect.sync(() => {
|
|
90
|
+
if (part.type === "tool-call" && part.providerExecuted !== true) {
|
|
91
|
+
toolCallIds.add(part.id);
|
|
92
|
+
}
|
|
93
|
+
if (part.type === "tool-result" && part.providerExecuted !== true && part.preliminary !== true) {
|
|
94
|
+
toolResultIds.add(part.id);
|
|
95
|
+
}
|
|
96
|
+
if (part.type === "tool-approval-request")
|
|
97
|
+
hasApproval = true;
|
|
98
|
+
})), Stream.tap((part) => part.type === "error" ? Effect.logError("Agent model response failed", streamErrorDetails(part.error)) : Effect.void), Stream.flatMap((part) => Stream.fromIterable(eventsForPart({ messageId, part, toolkit }))));
|
|
99
|
+
const continuation = Stream.suspend(() => {
|
|
100
|
+
if (hasApproval || toolCallIds.size === 0)
|
|
101
|
+
return Stream.empty;
|
|
102
|
+
if (![...toolCallIds].every((id) => toolResultIds.has(id))) {
|
|
103
|
+
return Stream.succeed({
|
|
104
|
+
type: "error",
|
|
105
|
+
code: "stream-failed"
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (round >= 5) {
|
|
109
|
+
return Stream.succeed({
|
|
110
|
+
type: "error",
|
|
111
|
+
code: "round-limit"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return agentRounds({
|
|
115
|
+
conversation,
|
|
116
|
+
messageId,
|
|
117
|
+
prompt: [],
|
|
118
|
+
round: round + 1,
|
|
119
|
+
toolkit
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
return Stream.concat(current, continuation);
|
|
123
|
+
});
|
|
124
|
+
const appendApproval = Effect.fn("AgentService.appendApproval")(function* (conversation, action) {
|
|
125
|
+
const history = yield* Ref.get(conversation.history);
|
|
126
|
+
let pendingToolCallId;
|
|
127
|
+
const respondedApprovalIds = new Set;
|
|
128
|
+
const resolvedToolCallIds = new Set;
|
|
129
|
+
for (const message of history.content) {
|
|
130
|
+
for (const part of message.content) {
|
|
131
|
+
if (typeof part === "string")
|
|
132
|
+
continue;
|
|
133
|
+
if (part.type === "tool-approval-request" && part.approvalId === action.approvalId) {
|
|
134
|
+
pendingToolCallId = part.toolCallId;
|
|
135
|
+
}
|
|
136
|
+
if (part.type === "tool-approval-response") {
|
|
137
|
+
respondedApprovalIds.add(part.approvalId);
|
|
138
|
+
}
|
|
139
|
+
if (part.type === "tool-result") {
|
|
140
|
+
resolvedToolCallIds.add(part.id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!pendingToolCallId || respondedApprovalIds.has(action.approvalId) || resolvedToolCallIds.has(pendingToolCallId)) {
|
|
145
|
+
return yield* new AgentHistoryError;
|
|
146
|
+
}
|
|
147
|
+
yield* Ref.set(conversation.history, Prompt.concat(history, [
|
|
148
|
+
Prompt.toolMessage({
|
|
149
|
+
content: [
|
|
150
|
+
Prompt.toolApprovalResponsePart({
|
|
151
|
+
approvalId: action.approvalId,
|
|
152
|
+
approved: action.approved
|
|
153
|
+
})
|
|
154
|
+
]
|
|
155
|
+
})
|
|
156
|
+
]));
|
|
157
|
+
});
|
|
158
|
+
const stream = Effect.fn("AgentService.stream")(function* ({ action, history, systemPrompt, toolkit }) {
|
|
159
|
+
const model = yield* LanguageModel.LanguageModel;
|
|
160
|
+
const messageId = crypto.randomUUID();
|
|
161
|
+
const conversation = history ? yield* Chat.fromJson(history) : yield* Chat.fromPrompt([{ role: "system", content: systemPrompt }]);
|
|
162
|
+
yield* Ref.update(conversation.history, Prompt.setSystem(systemPrompt));
|
|
163
|
+
if (action.type === "approval") {
|
|
164
|
+
yield* appendApproval(conversation, action);
|
|
165
|
+
}
|
|
166
|
+
const rounds = agentRounds({
|
|
167
|
+
conversation,
|
|
168
|
+
messageId,
|
|
169
|
+
prompt: action.type === "message" ? action.text : [],
|
|
170
|
+
round: 1,
|
|
171
|
+
toolkit
|
|
172
|
+
});
|
|
173
|
+
const complete = Stream.fromEffect(Effect.gen(function* () {
|
|
174
|
+
const history2 = yield* conversation.exportJson;
|
|
175
|
+
return { type: "history", value: history2 };
|
|
176
|
+
})).pipe(Stream.concat(Stream.succeed({ type: "finish" })));
|
|
177
|
+
const response = Stream.concat(rounds, complete).pipe(Stream.provideService(LanguageModel.LanguageModel, model), Stream.catch((error) => Stream.fromEffect(Effect.logError("Agent stream failed", streamErrorDetails(error))).pipe(Stream.drain, Stream.concat(Stream.make({
|
|
178
|
+
type: "error",
|
|
179
|
+
code: "stream-failed"
|
|
180
|
+
}, { type: "finish" })))));
|
|
181
|
+
return Stream.concat(Stream.succeed({ type: "message-start", messageId }), response);
|
|
182
|
+
});
|
|
183
|
+
return { stream };
|
|
184
|
+
})
|
|
185
|
+
}) {
|
|
186
|
+
static layer = Layer.effect(this, this.make);
|
|
187
|
+
}
|
|
188
|
+
export {
|
|
189
|
+
AgentService
|
|
190
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { HttpApiEndpoint, HttpApiError, HttpApiGroup, HttpApiSchema } from "effect/unstable/httpapi";
|
|
3
|
+
export declare const AGENT_REFERENCE_LIMIT = 20;
|
|
4
|
+
export type AgentReference<Resource> = {
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly resource: Resource;
|
|
7
|
+
};
|
|
8
|
+
export declare const makeAgentReference: <const Resource extends Schema.Top>(resource: Resource) => Schema.Struct<{
|
|
9
|
+
readonly label: Schema.String;
|
|
10
|
+
readonly resource: Resource;
|
|
11
|
+
}>;
|
|
12
|
+
export type AgentAction<Resource = never> = {
|
|
13
|
+
readonly type: "message";
|
|
14
|
+
readonly text: string;
|
|
15
|
+
readonly references?: ReadonlyArray<AgentReference<Resource>>;
|
|
16
|
+
} | {
|
|
17
|
+
readonly type: "approval";
|
|
18
|
+
readonly approvalId: string;
|
|
19
|
+
readonly approved: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare const AgentToolMetadata: Schema.Struct<{
|
|
22
|
+
readonly title: Schema.optional<Schema.String>;
|
|
23
|
+
readonly description: Schema.optional<Schema.String>;
|
|
24
|
+
readonly destructive: Schema.Boolean;
|
|
25
|
+
}>;
|
|
26
|
+
export declare const AgentEvent: Schema.Union<readonly [Schema.Struct<{
|
|
27
|
+
readonly type: Schema.Literal<"message-start">;
|
|
28
|
+
readonly messageId: Schema.String;
|
|
29
|
+
}>, Schema.Struct<{
|
|
30
|
+
readonly type: Schema.Literal<"text-delta">;
|
|
31
|
+
readonly messageId: Schema.String;
|
|
32
|
+
readonly delta: Schema.String;
|
|
33
|
+
}>, Schema.Struct<{
|
|
34
|
+
readonly type: Schema.Literal<"tool-call">;
|
|
35
|
+
readonly messageId: Schema.String;
|
|
36
|
+
readonly toolCallId: Schema.String;
|
|
37
|
+
readonly name: Schema.String;
|
|
38
|
+
readonly input: Schema.Unknown;
|
|
39
|
+
readonly metadata: Schema.Struct<{
|
|
40
|
+
readonly title: Schema.optional<Schema.String>;
|
|
41
|
+
readonly description: Schema.optional<Schema.String>;
|
|
42
|
+
readonly destructive: Schema.Boolean;
|
|
43
|
+
}>;
|
|
44
|
+
}>, Schema.Struct<{
|
|
45
|
+
readonly type: Schema.Literal<"tool-result">;
|
|
46
|
+
readonly toolCallId: Schema.String;
|
|
47
|
+
readonly name: Schema.String;
|
|
48
|
+
readonly isFailure: Schema.Boolean;
|
|
49
|
+
}>, Schema.Struct<{
|
|
50
|
+
readonly type: Schema.Literal<"approval-required">;
|
|
51
|
+
readonly approvalId: Schema.String;
|
|
52
|
+
readonly toolCallId: Schema.String;
|
|
53
|
+
}>, Schema.Struct<{
|
|
54
|
+
readonly type: Schema.Literal<"history">;
|
|
55
|
+
readonly value: Schema.String;
|
|
56
|
+
}>, Schema.Struct<{
|
|
57
|
+
readonly type: Schema.Literal<"finish">;
|
|
58
|
+
}>, Schema.Struct<{
|
|
59
|
+
readonly type: Schema.Literal<"error">;
|
|
60
|
+
readonly code: Schema.Literals<readonly ["unavailable", "invalid-request", "round-limit", "stream-failed"]>;
|
|
61
|
+
}>]>;
|
|
62
|
+
export type AgentEvent = typeof AgentEvent.Type;
|
|
63
|
+
export type AgentErrorCode = Extract<AgentEvent, {
|
|
64
|
+
readonly type: "error";
|
|
65
|
+
}>["code"];
|
|
66
|
+
export type AgentRequest<Resource> = {
|
|
67
|
+
readonly action: AgentAction<Resource>;
|
|
68
|
+
readonly context?: AgentReference<Resource>;
|
|
69
|
+
readonly history?: string;
|
|
70
|
+
};
|
|
71
|
+
export declare const makeAgentApiGroup: <const Resource extends Schema.Top>(resource: Resource) => HttpApiGroup.HttpApiGroup<"agent", HttpApiEndpoint.HttpApiEndpoint<"stream", "POST", "/agent", never, never, Schema.toCodecJson<Schema.Struct<{
|
|
72
|
+
readonly action: Schema.Union<readonly [Schema.Struct<{
|
|
73
|
+
readonly type: Schema.Literal<"message">;
|
|
74
|
+
readonly text: Schema.String;
|
|
75
|
+
readonly references: Schema.optional<Schema.$Array<Schema.Struct<{
|
|
76
|
+
readonly label: Schema.String;
|
|
77
|
+
readonly resource: Resource;
|
|
78
|
+
}>>>;
|
|
79
|
+
}>, Schema.Struct<{
|
|
80
|
+
readonly type: Schema.Literal<"approval">;
|
|
81
|
+
readonly approvalId: Schema.NonEmptyString;
|
|
82
|
+
readonly approved: Schema.Boolean;
|
|
83
|
+
}>]>;
|
|
84
|
+
readonly context: Schema.optional<Schema.Struct<{
|
|
85
|
+
readonly label: Schema.String;
|
|
86
|
+
readonly resource: Resource;
|
|
87
|
+
}>>;
|
|
88
|
+
readonly history: Schema.optional<Schema.String>;
|
|
89
|
+
}>>, never, HttpApiSchema.StreamSse<HttpApiSchema.SseEventFromData<Schema.Union<readonly [Schema.Struct<{
|
|
90
|
+
readonly type: Schema.Literal<"message-start">;
|
|
91
|
+
readonly messageId: Schema.String;
|
|
92
|
+
}>, Schema.Struct<{
|
|
93
|
+
readonly type: Schema.Literal<"text-delta">;
|
|
94
|
+
readonly messageId: Schema.String;
|
|
95
|
+
readonly delta: Schema.String;
|
|
96
|
+
}>, Schema.Struct<{
|
|
97
|
+
readonly type: Schema.Literal<"tool-call">;
|
|
98
|
+
readonly messageId: Schema.String;
|
|
99
|
+
readonly toolCallId: Schema.String;
|
|
100
|
+
readonly name: Schema.String;
|
|
101
|
+
readonly input: Schema.Unknown;
|
|
102
|
+
readonly metadata: Schema.Struct<{
|
|
103
|
+
readonly title: Schema.optional<Schema.String>;
|
|
104
|
+
readonly description: Schema.optional<Schema.String>;
|
|
105
|
+
readonly destructive: Schema.Boolean;
|
|
106
|
+
}>;
|
|
107
|
+
}>, Schema.Struct<{
|
|
108
|
+
readonly type: Schema.Literal<"tool-result">;
|
|
109
|
+
readonly toolCallId: Schema.String;
|
|
110
|
+
readonly name: Schema.String;
|
|
111
|
+
readonly isFailure: Schema.Boolean;
|
|
112
|
+
}>, Schema.Struct<{
|
|
113
|
+
readonly type: Schema.Literal<"approval-required">;
|
|
114
|
+
readonly approvalId: Schema.String;
|
|
115
|
+
readonly toolCallId: Schema.String;
|
|
116
|
+
}>, Schema.Struct<{
|
|
117
|
+
readonly type: Schema.Literal<"history">;
|
|
118
|
+
readonly value: Schema.String;
|
|
119
|
+
}>, Schema.Struct<{
|
|
120
|
+
readonly type: Schema.Literal<"finish">;
|
|
121
|
+
}>, Schema.Struct<{
|
|
122
|
+
readonly type: Schema.Literal<"error">;
|
|
123
|
+
readonly code: Schema.Literals<readonly ["unavailable", "invalid-request", "round-limit", "stream-failed"]>;
|
|
124
|
+
}>]>>, Schema.Struct<{
|
|
125
|
+
readonly code: Schema.Literals<readonly ["unavailable", "stream-failed"]>;
|
|
126
|
+
}>, Schema.Struct.ReadonlySide<{
|
|
127
|
+
readonly type: Schema.Literal<"message-start">;
|
|
128
|
+
readonly messageId: Schema.String;
|
|
129
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
130
|
+
readonly type: Schema.Literal<"text-delta">;
|
|
131
|
+
readonly messageId: Schema.String;
|
|
132
|
+
readonly delta: Schema.String;
|
|
133
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
134
|
+
readonly type: Schema.Literal<"tool-call">;
|
|
135
|
+
readonly messageId: Schema.String;
|
|
136
|
+
readonly toolCallId: Schema.String;
|
|
137
|
+
readonly name: Schema.String;
|
|
138
|
+
readonly input: Schema.Unknown;
|
|
139
|
+
readonly metadata: Schema.Struct<{
|
|
140
|
+
readonly title: Schema.optional<Schema.String>;
|
|
141
|
+
readonly description: Schema.optional<Schema.String>;
|
|
142
|
+
readonly destructive: Schema.Boolean;
|
|
143
|
+
}>;
|
|
144
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
145
|
+
readonly type: Schema.Literal<"tool-result">;
|
|
146
|
+
readonly toolCallId: Schema.String;
|
|
147
|
+
readonly name: Schema.String;
|
|
148
|
+
readonly isFailure: Schema.Boolean;
|
|
149
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
150
|
+
readonly type: Schema.Literal<"approval-required">;
|
|
151
|
+
readonly approvalId: Schema.String;
|
|
152
|
+
readonly toolCallId: Schema.String;
|
|
153
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
154
|
+
readonly type: Schema.Literal<"history">;
|
|
155
|
+
readonly value: Schema.String;
|
|
156
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
157
|
+
readonly type: Schema.Literal<"finish">;
|
|
158
|
+
}, "Type"> | Schema.Struct.ReadonlySide<{
|
|
159
|
+
readonly type: Schema.Literal<"error">;
|
|
160
|
+
readonly code: Schema.Literals<readonly ["unavailable", "invalid-request", "round-limit", "stream-failed"]>;
|
|
161
|
+
}, "Type">>, Schema.toCodecJson<typeof HttpApiError.BadRequest | typeof HttpApiError.Unauthorized | typeof HttpApiError.Forbidden | typeof HttpApiError.InternalServerError>, never, never>, false>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// ../../src/services/agent/schema.ts
|
|
2
|
+
import { Schema } from "effect";
|
|
3
|
+
import {
|
|
4
|
+
HttpApiEndpoint,
|
|
5
|
+
HttpApiError,
|
|
6
|
+
HttpApiGroup,
|
|
7
|
+
HttpApiSchema,
|
|
8
|
+
OpenApi
|
|
9
|
+
} from "effect/unstable/httpapi";
|
|
10
|
+
var AgentMessageText = Schema.String.check(Schema.isLengthBetween(1, 4000)).annotate({
|
|
11
|
+
identifier: "AgentMessageText",
|
|
12
|
+
title: "Agent message",
|
|
13
|
+
description: "A user message sent to the agent."
|
|
14
|
+
});
|
|
15
|
+
var AgentReferenceLabel = Schema.String.check(Schema.isLengthBetween(1, 500));
|
|
16
|
+
var AGENT_REFERENCE_LIMIT = 20;
|
|
17
|
+
var makeAgentReference = (resource) => Schema.Struct({
|
|
18
|
+
label: AgentReferenceLabel,
|
|
19
|
+
resource
|
|
20
|
+
}).annotate({
|
|
21
|
+
identifier: "AgentReference",
|
|
22
|
+
title: "Agent reference",
|
|
23
|
+
description: "A resource referenced by an agent message."
|
|
24
|
+
});
|
|
25
|
+
var makeAgentAction = (resource) => Schema.Union([
|
|
26
|
+
Schema.Struct({
|
|
27
|
+
type: Schema.Literal("message"),
|
|
28
|
+
text: AgentMessageText,
|
|
29
|
+
references: Schema.optional(Schema.Array(makeAgentReference(resource)).check(Schema.isMaxLength(AGENT_REFERENCE_LIMIT)))
|
|
30
|
+
}),
|
|
31
|
+
Schema.Struct({
|
|
32
|
+
type: Schema.Literal("approval"),
|
|
33
|
+
approvalId: Schema.NonEmptyString,
|
|
34
|
+
approved: Schema.Boolean
|
|
35
|
+
})
|
|
36
|
+
]).annotate({
|
|
37
|
+
identifier: "AgentAction",
|
|
38
|
+
title: "Agent action",
|
|
39
|
+
description: "A message with optional references or a tool approval response."
|
|
40
|
+
});
|
|
41
|
+
var AgentToolMetadata = Schema.Struct({
|
|
42
|
+
title: Schema.optional(Schema.String),
|
|
43
|
+
description: Schema.optional(Schema.String),
|
|
44
|
+
destructive: Schema.Boolean
|
|
45
|
+
}).annotate({ identifier: "AgentToolMetadata" });
|
|
46
|
+
var AgentEvent = Schema.Union([
|
|
47
|
+
Schema.Struct({
|
|
48
|
+
type: Schema.Literal("message-start"),
|
|
49
|
+
messageId: Schema.String
|
|
50
|
+
}),
|
|
51
|
+
Schema.Struct({
|
|
52
|
+
type: Schema.Literal("text-delta"),
|
|
53
|
+
messageId: Schema.String,
|
|
54
|
+
delta: Schema.String
|
|
55
|
+
}),
|
|
56
|
+
Schema.Struct({
|
|
57
|
+
type: Schema.Literal("tool-call"),
|
|
58
|
+
messageId: Schema.String,
|
|
59
|
+
toolCallId: Schema.String,
|
|
60
|
+
name: Schema.String,
|
|
61
|
+
input: Schema.Unknown,
|
|
62
|
+
metadata: AgentToolMetadata
|
|
63
|
+
}),
|
|
64
|
+
Schema.Struct({
|
|
65
|
+
type: Schema.Literal("tool-result"),
|
|
66
|
+
toolCallId: Schema.String,
|
|
67
|
+
name: Schema.String,
|
|
68
|
+
isFailure: Schema.Boolean
|
|
69
|
+
}),
|
|
70
|
+
Schema.Struct({
|
|
71
|
+
type: Schema.Literal("approval-required"),
|
|
72
|
+
approvalId: Schema.String,
|
|
73
|
+
toolCallId: Schema.String
|
|
74
|
+
}),
|
|
75
|
+
Schema.Struct({
|
|
76
|
+
type: Schema.Literal("history"),
|
|
77
|
+
value: Schema.String
|
|
78
|
+
}),
|
|
79
|
+
Schema.Struct({ type: Schema.Literal("finish") }),
|
|
80
|
+
Schema.Struct({
|
|
81
|
+
type: Schema.Literal("error"),
|
|
82
|
+
code: Schema.Literals([
|
|
83
|
+
"unavailable",
|
|
84
|
+
"invalid-request",
|
|
85
|
+
"round-limit",
|
|
86
|
+
"stream-failed"
|
|
87
|
+
])
|
|
88
|
+
})
|
|
89
|
+
]).annotate({
|
|
90
|
+
identifier: "AgentEvent",
|
|
91
|
+
title: "Agent stream event",
|
|
92
|
+
description: "An event emitted by the agent endpoint."
|
|
93
|
+
});
|
|
94
|
+
var AgentStreamError = Schema.Struct({
|
|
95
|
+
code: Schema.Literals(["unavailable", "stream-failed"])
|
|
96
|
+
}).annotate({
|
|
97
|
+
identifier: "AgentStreamError",
|
|
98
|
+
title: "Agent stream error",
|
|
99
|
+
description: "A recoverable agent stream failure."
|
|
100
|
+
});
|
|
101
|
+
var makeAgentApiGroup = (resource) => {
|
|
102
|
+
const AgentAction = makeAgentAction(resource);
|
|
103
|
+
const AgentRequest = Schema.Struct({
|
|
104
|
+
action: AgentAction,
|
|
105
|
+
context: Schema.optional(makeAgentReference(resource)),
|
|
106
|
+
history: Schema.optional(Schema.String.check(Schema.isMaxLength(500000)))
|
|
107
|
+
}).annotate({
|
|
108
|
+
identifier: "AgentRequest",
|
|
109
|
+
title: "Agent request",
|
|
110
|
+
description: "An authenticated agent request."
|
|
111
|
+
});
|
|
112
|
+
return HttpApiGroup.make("agent").add(HttpApiEndpoint.post("stream", "/agent", {
|
|
113
|
+
payload: AgentRequest,
|
|
114
|
+
success: HttpApiSchema.StreamSse({
|
|
115
|
+
data: AgentEvent,
|
|
116
|
+
error: AgentStreamError
|
|
117
|
+
}),
|
|
118
|
+
error: [
|
|
119
|
+
HttpApiError.BadRequest,
|
|
120
|
+
HttpApiError.Unauthorized,
|
|
121
|
+
HttpApiError.Forbidden,
|
|
122
|
+
HttpApiError.InternalServerError
|
|
123
|
+
]
|
|
124
|
+
}).annotateMerge(OpenApi.annotations({
|
|
125
|
+
summary: "Stream agent",
|
|
126
|
+
description: "Streams an AI agent response for the current session."
|
|
127
|
+
})));
|
|
128
|
+
};
|
|
129
|
+
export {
|
|
130
|
+
makeAgentReference,
|
|
131
|
+
makeAgentApiGroup,
|
|
132
|
+
AgentToolMetadata,
|
|
133
|
+
AgentEvent,
|
|
134
|
+
AGENT_REFERENCE_LIMIT
|
|
135
|
+
};
|