@popcomputer/structured-chat 0.1.0 → 0.2.0-rc.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.
- package/LICENSE +0 -1
- package/README.md +122 -108
- package/dist/adapters/openai-compatible-model.d.ts +4 -4
- package/dist/adapters/openai-compatible-model.js +33 -31
- package/dist/core/answer.d.ts +13 -13
- package/dist/core/answer.js +21 -12
- package/dist/core/chat.d.ts +12 -15
- package/dist/core/chat.js +36 -27
- package/dist/core/collect-stage.d.ts +11 -14
- package/dist/core/collect-stage.js +40 -37
- package/dist/core/command.d.ts +1 -1
- package/dist/core/command.js +1 -1
- package/dist/core/json-value.d.ts +1 -1
- package/dist/core/json-value.js +8 -1
- package/dist/core/model-guard.d.ts +2 -3
- package/dist/core/model-guard.js +4 -4
- package/dist/core/model.d.ts +15 -19
- package/dist/core/model.js +22 -10
- package/dist/core/protocol.d.ts +84 -79
- package/dist/core/protocol.js +18 -12
- package/dist/core/question.js +17 -15
- package/dist/core/repair.js +1 -1
- package/dist/core/session.d.ts +22 -28
- package/dist/core/session.js +16 -7
- package/dist/core/stage-name.d.ts +1 -1
- package/dist/core/stage-name.js +1 -1
- package/dist/core/stage.d.ts +4 -4
- package/dist/core/stage.js +11 -8
- package/dist/core/tool-set.js +6 -6
- package/dist/core/tool.d.ts +36 -39
- package/dist/core/tool.js +58 -31
- package/dist/core/view.d.ts +64 -39
- package/dist/core/view.js +12 -15
- package/dist/integrations/assistant-ui.js +21 -14
- package/dist/testing/in-memory-session-store.js +1 -1
- package/dist/testing/scenario.js +6 -6
- package/examples/answer-modes.ts +60 -49
- package/examples/prompt-injection-policy.ts +20 -20
- package/examples/resource-search.ts +104 -0
- package/package.json +11 -3
- package/examples/agency-search.ts +0 -101
package/dist/core/session.d.ts
CHANGED
|
@@ -1,53 +1,47 @@
|
|
|
1
1
|
import { Context, Effect, Schema } from "effect";
|
|
2
2
|
import { type UntrustedMessage } from "./model.js";
|
|
3
3
|
/** Stable application-owned identifier for one chat session. */
|
|
4
|
-
export declare const ChatSessionIdSchema: Schema.
|
|
4
|
+
export declare const ChatSessionIdSchema: Schema.Trimmed;
|
|
5
5
|
/** Optional application-owned partition for otherwise public session IDs. */
|
|
6
|
-
export declare const ChatSessionNamespaceSchema: Schema.
|
|
6
|
+
export declare const ChatSessionNamespaceSchema: Schema.Trimmed;
|
|
7
7
|
/** Opaque optimistic revision emitted by a session store adapter. */
|
|
8
|
-
export declare const ChatSessionRevisionSchema: Schema.
|
|
8
|
+
export declare const ChatSessionRevisionSchema: Schema.Trimmed;
|
|
9
9
|
/** Persisted session snapshot revalidated by the chat runtime after loading. */
|
|
10
10
|
export declare const ChatSessionSnapshotSchema: Schema.Struct<{
|
|
11
|
-
revision: Schema.
|
|
12
|
-
state:
|
|
13
|
-
messages: Schema
|
|
14
|
-
role: Schema.
|
|
15
|
-
content: Schema.
|
|
16
|
-
}
|
|
11
|
+
readonly revision: Schema.Trimmed;
|
|
12
|
+
readonly state: Schema.Unknown;
|
|
13
|
+
readonly messages: Schema.$Array<Schema.Struct<{
|
|
14
|
+
readonly role: Schema.Literals<readonly ["user", "assistant"]>;
|
|
15
|
+
readonly content: Schema.Trimmed;
|
|
16
|
+
}>>;
|
|
17
17
|
}>;
|
|
18
18
|
/** Parsed persisted chat session snapshot. */
|
|
19
19
|
export type ChatSessionSnapshot = Schema.Schema.Type<typeof ChatSessionSnapshotSchema>;
|
|
20
20
|
/** Successful optimistic session replacement returned by an adapter. */
|
|
21
21
|
export declare const ChatSessionReplacementSchema: Schema.Struct<{
|
|
22
|
-
revision: Schema.
|
|
22
|
+
readonly revision: Schema.Trimmed;
|
|
23
23
|
}>;
|
|
24
24
|
/** Successful optimistic session replacement returned by an adapter. */
|
|
25
25
|
export type ChatSessionReplacement = Schema.Schema.Type<typeof ChatSessionReplacementSchema>;
|
|
26
26
|
/** Safe reason that a session store dependency was unavailable. */
|
|
27
|
-
export declare const ChatSessionStoreUnavailableReasonSchema: Schema.
|
|
28
|
-
declare const ChatSessionStoreUnavailable_base: Schema.
|
|
29
|
-
readonly
|
|
30
|
-
}
|
|
31
|
-
reason: Schema.Literal<["load_failed", "write_failed"]>;
|
|
32
|
-
}>;
|
|
27
|
+
export declare const ChatSessionStoreUnavailableReasonSchema: Schema.Literals<readonly ["load_failed", "write_failed"]>;
|
|
28
|
+
declare const ChatSessionStoreUnavailable_base: Schema.Class<ChatSessionStoreUnavailable, Schema.TaggedStruct<"ChatSessionStoreUnavailable", {
|
|
29
|
+
readonly reason: Schema.Literals<readonly ["load_failed", "write_failed"]>;
|
|
30
|
+
}>, import("effect/Cause").YieldableError>;
|
|
33
31
|
/** A session store adapter could not load or replace state. */
|
|
34
32
|
export declare class ChatSessionStoreUnavailable extends ChatSessionStoreUnavailable_base {
|
|
35
33
|
}
|
|
36
|
-
declare const ChatSessionConflict_base: Schema.
|
|
37
|
-
readonly
|
|
38
|
-
}
|
|
39
|
-
reason: Schema.Literal<["concurrent_update"]>;
|
|
40
|
-
}>;
|
|
34
|
+
declare const ChatSessionConflict_base: Schema.Class<ChatSessionConflict, Schema.TaggedStruct<"ChatSessionConflict", {
|
|
35
|
+
readonly reason: Schema.Literal<"concurrent_update">;
|
|
36
|
+
}>, import("effect/Cause").YieldableError>;
|
|
41
37
|
/** A concurrent or stale transition attempted to replace newer state. */
|
|
42
38
|
export declare class ChatSessionConflict extends ChatSessionConflict_base {
|
|
43
39
|
}
|
|
44
40
|
/** Safe reason that session input or persisted data was rejected. */
|
|
45
|
-
export declare const InvalidChatSessionReasonSchema: Schema.
|
|
46
|
-
declare const InvalidChatSession_base: Schema.
|
|
47
|
-
readonly
|
|
48
|
-
}
|
|
49
|
-
reason: Schema.Literal<["invalid_input", "invalid_snapshot", "invalid_state", "invalid_replacement", "history_limit"]>;
|
|
50
|
-
}>;
|
|
41
|
+
export declare const InvalidChatSessionReasonSchema: Schema.Literals<readonly ["invalid_input", "invalid_snapshot", "invalid_state", "invalid_replacement", "history_limit"]>;
|
|
42
|
+
declare const InvalidChatSession_base: Schema.Class<InvalidChatSession, Schema.TaggedStruct<"InvalidChatSession", {
|
|
43
|
+
readonly reason: Schema.Literals<readonly ["invalid_input", "invalid_snapshot", "invalid_state", "invalid_replacement", "history_limit"]>;
|
|
44
|
+
}>, import("effect/Cause").YieldableError>;
|
|
51
45
|
/** Session input or persisted state failed runtime validation. */
|
|
52
46
|
export declare class InvalidChatSession extends InvalidChatSession_base {
|
|
53
47
|
}
|
|
@@ -71,7 +65,7 @@ export interface ChatSessionStoreService {
|
|
|
71
65
|
/** Atomically replace one complete session at its expected revision. */
|
|
72
66
|
readonly replace: (input: ReplaceChatSessionInput) => Effect.Effect<unknown, ChatSessionStoreUnavailable | ChatSessionConflict>;
|
|
73
67
|
}
|
|
74
|
-
declare const ChatSessionStore_base: Context.
|
|
68
|
+
declare const ChatSessionStore_base: Context.ServiceClass<ChatSessionStore, "@popcomputer/structured-chat/ChatSessionStore", ChatSessionStoreService>;
|
|
75
69
|
/** Effect service for the configured server-owned chat session store. */
|
|
76
70
|
export declare class ChatSessionStore extends ChatSessionStore_base {
|
|
77
71
|
}
|
package/dist/core/session.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { Context, Effect, Schema } from "effect";
|
|
2
2
|
import { UntrustedMessageSchema } from "./model.js";
|
|
3
3
|
/** Stable application-owned identifier for one chat session. */
|
|
4
|
-
export const ChatSessionIdSchema = Schema.
|
|
4
|
+
export const ChatSessionIdSchema = Schema.Trimmed.check(Schema.isNonEmpty(), Schema.isMaxLength(200), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/));
|
|
5
5
|
/** Optional application-owned partition for otherwise public session IDs. */
|
|
6
|
-
export const ChatSessionNamespaceSchema = Schema.
|
|
6
|
+
export const ChatSessionNamespaceSchema = Schema.Trimmed.check(Schema.isNonEmpty(), Schema.isMaxLength(200), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/));
|
|
7
7
|
/** Opaque optimistic revision emitted by a session store adapter. */
|
|
8
|
-
export const ChatSessionRevisionSchema = Schema.
|
|
8
|
+
export const ChatSessionRevisionSchema = Schema.Trimmed.check(Schema.isNonEmpty(), Schema.isMaxLength(200), Schema.isPattern(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/));
|
|
9
9
|
/** Persisted session snapshot revalidated by the chat runtime after loading. */
|
|
10
10
|
export const ChatSessionSnapshotSchema = Schema.Struct({
|
|
11
11
|
revision: ChatSessionRevisionSchema,
|
|
12
12
|
state: Schema.Unknown,
|
|
13
|
-
messages: Schema.Array(UntrustedMessageSchema).
|
|
13
|
+
messages: Schema.Array(UntrustedMessageSchema).check(Schema.isMaxLength(200)),
|
|
14
14
|
});
|
|
15
15
|
/** Successful optimistic session replacement returned by an adapter. */
|
|
16
16
|
export const ChatSessionReplacementSchema = Schema.Struct({
|
|
17
17
|
revision: ChatSessionRevisionSchema,
|
|
18
18
|
});
|
|
19
19
|
/** Safe reason that a session store dependency was unavailable. */
|
|
20
|
-
export const ChatSessionStoreUnavailableReasonSchema = Schema.
|
|
20
|
+
export const ChatSessionStoreUnavailableReasonSchema = Schema.Literals([
|
|
21
|
+
"load_failed",
|
|
22
|
+
"write_failed",
|
|
23
|
+
]);
|
|
21
24
|
/** A session store adapter could not load or replace state. */
|
|
22
25
|
export class ChatSessionStoreUnavailable extends Schema.TaggedError()("ChatSessionStoreUnavailable", { reason: ChatSessionStoreUnavailableReasonSchema }) {
|
|
23
26
|
}
|
|
@@ -25,10 +28,16 @@ export class ChatSessionStoreUnavailable extends Schema.TaggedError()("ChatSessi
|
|
|
25
28
|
export class ChatSessionConflict extends Schema.TaggedError()("ChatSessionConflict", { reason: Schema.Literal("concurrent_update") }) {
|
|
26
29
|
}
|
|
27
30
|
/** Safe reason that session input or persisted data was rejected. */
|
|
28
|
-
export const InvalidChatSessionReasonSchema = Schema.
|
|
31
|
+
export const InvalidChatSessionReasonSchema = Schema.Literals([
|
|
32
|
+
"invalid_input",
|
|
33
|
+
"invalid_snapshot",
|
|
34
|
+
"invalid_state",
|
|
35
|
+
"invalid_replacement",
|
|
36
|
+
"history_limit",
|
|
37
|
+
]);
|
|
29
38
|
/** Session input or persisted state failed runtime validation. */
|
|
30
39
|
export class InvalidChatSession extends Schema.TaggedError()("InvalidChatSession", { reason: InvalidChatSessionReasonSchema }) {
|
|
31
40
|
}
|
|
32
41
|
/** Effect service for the configured server-owned chat session store. */
|
|
33
|
-
export class ChatSessionStore extends Context.
|
|
42
|
+
export class ChatSessionStore extends Context.Service()("@popcomputer/structured-chat/ChatSessionStore") {
|
|
34
43
|
}
|
package/dist/core/stage-name.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
/** Stable machine-facing name for one structured chat stage. */
|
|
3
|
-
export const StageNameSchema = Schema.
|
|
3
|
+
export const StageNameSchema = Schema.Trimmed.check(Schema.isNonEmpty(), Schema.isMaxLength(100), Schema.isPattern(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/));
|
package/dist/core/stage.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { Effect, Schema } from "effect";
|
|
|
2
2
|
import { StructuredChatModel, type ChatModelUnavailable, type UnsupportedModelToolSchema, type UntrustedMessage } from "./model.js";
|
|
3
3
|
import type { ModelGuardError, ModelGuardRequirements, ModelGuardTuple } from "./model-guard.js";
|
|
4
4
|
import { type ToolSet, type ToolSetCall, type ToolSetError, type ToolSetExecution, type ToolSetRequirements, type ToolTuple } from "./tool-set.js";
|
|
5
|
-
import type { CommandDefinitionContract, CommandExecutionContext, InvalidToolCall, InvalidToolProjection, StructuredCommand, ToolCall, ToolExecution, QueryToolDefinitionContract } from "./tool.js";
|
|
5
|
+
import type { CommandDefinitionContract, CommandExecutionContext, InvalidToolCall, InvalidToolProjection, StructuredCommand, ToolCall, ToolExecution, QueryToolDefinitionContract, ToolSchema } from "./tool.js";
|
|
6
6
|
import { type StructuredDefinition } from "./definition.js";
|
|
7
7
|
export { StageNameSchema } from "./stage-name.js";
|
|
8
8
|
/** State transition applied after one tool-stage execution. */
|
|
9
|
-
export declare const ToolStageAfterExecutionSchema: Schema.
|
|
9
|
+
export declare const ToolStageAfterExecutionSchema: Schema.Literals<readonly ["stay", "complete"]>;
|
|
10
10
|
/** State transition applied after one tool-stage execution. */
|
|
11
11
|
export type ToolStageAfterExecution = Schema.Schema.Type<typeof ToolStageAfterExecutionSchema>;
|
|
12
12
|
/** Definition input for one stage-scoped, repeatable tool step. */
|
|
@@ -21,8 +21,8 @@ export interface DefineToolStageInput<Name extends string, Tools extends ToolTup
|
|
|
21
21
|
export interface ToolStageRuntime {
|
|
22
22
|
readonly afterExecution: ToolStageAfterExecution;
|
|
23
23
|
readonly toolNames: ReadonlyArray<string>;
|
|
24
|
-
readonly planWith: (messages: ReadonlyArray<UntrustedMessage>, additionalTool: QueryToolDefinitionContract) => Effect.Effect<ToolCall<string,
|
|
25
|
-
readonly execute: (call: ToolCall<string,
|
|
24
|
+
readonly planWith: (messages: ReadonlyArray<UntrustedMessage>, additionalTool: QueryToolDefinitionContract) => Effect.Effect<ToolCall<string, ToolSchema>, unknown, unknown>;
|
|
25
|
+
readonly execute: (call: ToolCall<string, ToolSchema>) => Effect.Effect<unknown, unknown, unknown>;
|
|
26
26
|
readonly run: (messages: ReadonlyArray<UntrustedMessage>) => Effect.Effect<unknown, unknown, unknown>;
|
|
27
27
|
}
|
|
28
28
|
declare const toolStageRuntime: unique symbol;
|
package/dist/core/stage.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect,
|
|
1
|
+
import { Effect, Function as Fn, Schema } from "effect";
|
|
2
2
|
import { Instruction, planToolCall, StructuredChatModel, } from "./model.js";
|
|
3
3
|
import { defineToolSet, } from "./tool-set.js";
|
|
4
4
|
import { defineCollectStage } from "./collect-stage.js";
|
|
@@ -6,7 +6,10 @@ import { StageNameSchema } from "./stage-name.js";
|
|
|
6
6
|
import { structuredDefinition, } from "./definition.js";
|
|
7
7
|
export { StageNameSchema } from "./stage-name.js";
|
|
8
8
|
/** State transition applied after one tool-stage execution. */
|
|
9
|
-
export const ToolStageAfterExecutionSchema = Schema.
|
|
9
|
+
export const ToolStageAfterExecutionSchema = Schema.Literals([
|
|
10
|
+
"stay",
|
|
11
|
+
"complete",
|
|
12
|
+
]);
|
|
10
13
|
const toolStageRuntime = Symbol("@popcomputer/structured-chat/ToolStageRuntime");
|
|
11
14
|
/** @internal Read the erased runtime from an authentic tool stage. */
|
|
12
15
|
export const readToolStageRuntime = (stage) => stage[toolStageRuntime];
|
|
@@ -19,7 +22,7 @@ const defineToolStage = (definition) => {
|
|
|
19
22
|
const toolSet = defineToolSet(...definition.tools);
|
|
20
23
|
// SAFETY: when guards are omitted, Guards uses its readonly [] default; an
|
|
21
24
|
// explicitly supplied tuple is returned unchanged.
|
|
22
|
-
const guards = definition.guards ??
|
|
25
|
+
const guards = definition.guards ?? Fn.cast([]);
|
|
23
26
|
const afterExecution = Schema.decodeSync(ToolStageAfterExecutionSchema)(definition.afterExecution ?? "stay");
|
|
24
27
|
const plan = (messages) => planToolCall({
|
|
25
28
|
instructions,
|
|
@@ -32,7 +35,7 @@ const defineToolStage = (definition) => {
|
|
|
32
35
|
const run = (messages) => plan(messages).pipe(Effect.flatMap(toolSet.execute));
|
|
33
36
|
// SAFETY: chat repair supplies only a call parsed by a combined set that
|
|
34
37
|
// contains this exact query tuple; non-repair names therefore belong here.
|
|
35
|
-
const executeRuntime = toolSet.execute;
|
|
38
|
+
const executeRuntime = Fn.cast(toolSet.execute);
|
|
36
39
|
const planWith = (messages, additionalTool) => {
|
|
37
40
|
// SAFETY: the additional package-owned query and this non-empty exact
|
|
38
41
|
// query tuple form another valid closed tool set for planning only.
|
|
@@ -65,24 +68,24 @@ const defineCommandStage = (definition) => {
|
|
|
65
68
|
Schema.decodeSync(StageNameSchema)(definition.name);
|
|
66
69
|
const instructions = definition.instructions.map(Instruction.make);
|
|
67
70
|
// SAFETY: when omitted, Guards is its readonly [] default.
|
|
68
|
-
const guards = definition.guards ??
|
|
71
|
+
const guards = definition.guards ?? Fn.cast([]);
|
|
69
72
|
const planner = {
|
|
70
73
|
models: [definition.command.model],
|
|
71
74
|
// SAFETY: this command parses its literal name and exact input schema.
|
|
72
|
-
parseCall: definition.command.parseCall,
|
|
75
|
+
parseCall: Fn.cast(definition.command.parseCall),
|
|
73
76
|
};
|
|
74
77
|
const plan = (messages) => planToolCall({ instructions, messages, tools: planner, guards }).pipe(Effect.withSpan("popcomputer.structured_chat.command_stage.plan", {
|
|
75
78
|
attributes: { stage: definition.name },
|
|
76
79
|
}));
|
|
77
80
|
// SAFETY: Command has the package-owned identity and command operation;
|
|
78
81
|
// its parsed call and runtime execute input originate from one definition.
|
|
79
|
-
const runtimeCommand =
|
|
82
|
+
const runtimeCommand = Fn.cast(definition.command);
|
|
80
83
|
const runRuntime = (messages, context) => plan(messages).pipe(Effect.flatMap((call) => runtimeCommand.execute(call.arguments, context)), Effect.withSpan("popcomputer.structured_chat.command_stage.run", {
|
|
81
84
|
attributes: { stage: definition.name },
|
|
82
85
|
}));
|
|
83
86
|
// SAFETY: failures and requirements are not recovered; the command's
|
|
84
87
|
// projections and result are preserved by its own execute operation.
|
|
85
|
-
const run = runRuntime;
|
|
88
|
+
const run = Fn.cast(runRuntime);
|
|
86
89
|
return structuredDefinition("command_stage")({
|
|
87
90
|
_tag: "CommandStage",
|
|
88
91
|
name: definition.name,
|
package/dist/core/tool-set.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect,
|
|
1
|
+
import { Effect, Function as Fn, Schema } from "effect";
|
|
2
2
|
import { InvalidToolCall as InvalidToolCallError, InvalidToolCallReasonSchema, ToolNameSchema, } from "./tool.js";
|
|
3
3
|
import { JsonValueSchema } from "./json-value.js";
|
|
4
4
|
const IncomingToolCallSchema = Schema.Struct({
|
|
@@ -28,7 +28,7 @@ export const defineToolSet = (...tools) => {
|
|
|
28
28
|
// SAFETY: ToolDefinitionContract carries the package-owned nominal identity.
|
|
29
29
|
// Runtime execution is erased here and restored by ToolSet's conditional
|
|
30
30
|
// public result, error, and requirement types.
|
|
31
|
-
runtimeTools.set(tool.name,
|
|
31
|
+
runtimeTools.set(tool.name, Fn.cast(tool));
|
|
32
32
|
}
|
|
33
33
|
const selectTool = (name) => {
|
|
34
34
|
const tool = runtimeTools.get(name);
|
|
@@ -37,21 +37,21 @@ export const defineToolSet = (...tools) => {
|
|
|
37
37
|
}
|
|
38
38
|
return Effect.succeed(tool);
|
|
39
39
|
};
|
|
40
|
-
const parseCallRuntime = (input) => Schema.
|
|
40
|
+
const parseCallRuntime = (input) => Schema.decodeUnknownEffect(IncomingToolCallSchema)(input, {
|
|
41
41
|
onExcessProperty: "error",
|
|
42
42
|
}).pipe(Effect.mapError(() => invalidCall("invalid_envelope", null)), Effect.flatMap((call) => selectTool(call.name).pipe(Effect.flatMap((tool) => tool.parseCall(call)))), Effect.withSpan("popcomputer.structured_chat.tool_set.parse", {
|
|
43
43
|
attributes: { toolCount: tools.length },
|
|
44
44
|
}));
|
|
45
45
|
// SAFETY: the envelope parser establishes a registered name, then that
|
|
46
46
|
// registered tool parses its own literal name and argument schema.
|
|
47
|
-
const parseCall = parseCallRuntime;
|
|
47
|
+
const parseCall = Fn.cast(parseCallRuntime);
|
|
48
48
|
const executeRuntime = (call) => selectTool(call.name).pipe(Effect.flatMap((tool) => tool.execute(call.arguments)), Effect.withSpan("popcomputer.structured_chat.tool_set.execute", {
|
|
49
49
|
attributes: { toolCount: tools.length },
|
|
50
50
|
}));
|
|
51
51
|
// SAFETY: call is a parsed member of ToolSetCall<Tools>; dispatch selects
|
|
52
52
|
// that member's registered runtime and passes its decoded arguments to the
|
|
53
53
|
// corresponding Type-side execute operation.
|
|
54
|
-
const execute = executeRuntime;
|
|
54
|
+
const execute = Fn.cast(executeRuntime);
|
|
55
55
|
const executeCall = (input) => parseCall(input).pipe(Effect.flatMap(execute));
|
|
56
56
|
return {
|
|
57
57
|
tools,
|
|
@@ -61,6 +61,6 @@ export const defineToolSet = (...tools) => {
|
|
|
61
61
|
// SAFETY: dispatch selects a member of Tools by its unique runtime name.
|
|
62
62
|
// Each tool parses itself before executing, so the resulting union exactly
|
|
63
63
|
// matches ToolSetExecution, ToolSetError, and ToolSetRequirements.
|
|
64
|
-
executeCall: executeCall,
|
|
64
|
+
executeCall: Fn.cast(executeCall),
|
|
65
65
|
};
|
|
66
66
|
};
|
package/dist/core/tool.d.ts
CHANGED
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
import { Effect,
|
|
2
|
-
import * as ParseResult from "effect/ParseResult";
|
|
1
|
+
import { Effect, JsonSchema, Pipeable, Schema } from "effect";
|
|
3
2
|
import type { ViewDefinitionContract, ViewInput, ViewPart } from "./view.js";
|
|
4
3
|
import { type StructuredDefinition } from "./definition.js";
|
|
5
4
|
import type { CommandId } from "./command.js";
|
|
6
5
|
import type { JsonValue } from "./json-value.js";
|
|
7
6
|
/** Stable machine-facing name for one structured chat tool. */
|
|
8
|
-
export declare const ToolNameSchema: Schema.
|
|
7
|
+
export declare const ToolNameSchema: Schema.Trimmed;
|
|
9
8
|
/** Bounded model-facing description for one structured chat tool. */
|
|
10
|
-
export declare const ToolDescriptionSchema: Schema.
|
|
9
|
+
export declare const ToolDescriptionSchema: Schema.Trimmed;
|
|
11
10
|
/** Safe reason that a model-authored tool call was rejected. */
|
|
12
|
-
export declare const InvalidToolCallReasonSchema: Schema.
|
|
13
|
-
declare const InvalidToolCall_base: Schema.
|
|
14
|
-
readonly
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
path: Schema.NullOr<Schema.filter<typeof Schema.NonEmptyTrimmedString>>;
|
|
19
|
-
}>;
|
|
11
|
+
export declare const InvalidToolCallReasonSchema: Schema.Literals<readonly ["invalid_envelope", "unknown_tool", "invalid_arguments"]>;
|
|
12
|
+
declare const InvalidToolCall_base: Schema.Class<InvalidToolCall, Schema.TaggedStruct<"InvalidToolCall", {
|
|
13
|
+
readonly tool: Schema.NullOr<Schema.Trimmed>;
|
|
14
|
+
readonly reason: Schema.Literals<readonly ["invalid_envelope", "unknown_tool", "invalid_arguments"]>;
|
|
15
|
+
readonly path: Schema.NullOr<Schema.Trimmed>;
|
|
16
|
+
}>, import("effect/Cause").YieldableError>;
|
|
20
17
|
/** A model-authored tool call failed strict parsing. */
|
|
21
18
|
export declare class InvalidToolCall extends InvalidToolCall_base {
|
|
22
19
|
}
|
|
23
20
|
/** Safe reason that an application-owned tool projection was rejected. */
|
|
24
|
-
export declare const InvalidToolProjectionReasonSchema: Schema.
|
|
25
|
-
declare const InvalidToolProjection_base: Schema.
|
|
26
|
-
readonly
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
reason: Schema.Literal<["invalid_model_result", "invalid_view_data"]>;
|
|
31
|
-
}>;
|
|
21
|
+
export declare const InvalidToolProjectionReasonSchema: Schema.Literals<readonly ["invalid_model_result", "invalid_view_data"]>;
|
|
22
|
+
declare const InvalidToolProjection_base: Schema.Class<InvalidToolProjection, Schema.TaggedStruct<"InvalidToolProjection", {
|
|
23
|
+
readonly tool: Schema.Trimmed;
|
|
24
|
+
readonly target: Schema.String;
|
|
25
|
+
readonly reason: Schema.Literals<readonly ["invalid_model_result", "invalid_view_data"]>;
|
|
26
|
+
}>, import("effect/Cause").YieldableError>;
|
|
32
27
|
/** An application-owned model or view projection violated its schema. */
|
|
33
28
|
export declare class InvalidToolProjection extends InvalidToolProjection_base {
|
|
34
29
|
}
|
|
@@ -36,8 +31,10 @@ export declare class InvalidToolProjection extends InvalidToolProjection_base {
|
|
|
36
31
|
export interface ModelToolDefinition<Name extends string = string> {
|
|
37
32
|
readonly name: Name;
|
|
38
33
|
readonly description: string;
|
|
39
|
-
readonly inputSchema:
|
|
34
|
+
readonly inputSchema: JsonSchema.JsonSchema;
|
|
40
35
|
}
|
|
36
|
+
/** Schema accepted at tool boundaries without runtime services. */
|
|
37
|
+
export type ToolSchema = Schema.Codec<unknown, unknown, never, never>;
|
|
41
38
|
/** Whether an executable model capability is repeatable or side-effecting. */
|
|
42
39
|
export type ToolOperation = "query" | "command";
|
|
43
40
|
/** Opaque stable identity supplied when a command executes. */
|
|
@@ -50,7 +47,7 @@ export interface ToolDefinitionContract extends StructuredDefinition<"tool"> {
|
|
|
50
47
|
readonly operation: ToolOperation;
|
|
51
48
|
readonly name: string;
|
|
52
49
|
readonly description: string;
|
|
53
|
-
readonly inputSchema:
|
|
50
|
+
readonly inputSchema: ToolSchema;
|
|
54
51
|
readonly model: ModelToolDefinition;
|
|
55
52
|
}
|
|
56
53
|
/** Minimum runtime shape retained for a repeatable read-only query. */
|
|
@@ -60,10 +57,10 @@ export interface QueryToolDefinitionContract extends ToolDefinitionContract {
|
|
|
60
57
|
/** Minimum runtime shape retained for a side-effecting command. */
|
|
61
58
|
export interface CommandDefinitionContract extends ToolDefinitionContract {
|
|
62
59
|
readonly operation: "command";
|
|
63
|
-
readonly parseCall: (input: JsonValue) => Effect.Effect<ToolCall<string,
|
|
60
|
+
readonly parseCall: (input: JsonValue) => Effect.Effect<ToolCall<string, ToolSchema>, InvalidToolCall>;
|
|
64
61
|
}
|
|
65
62
|
/** One model-authored, schema-parsed tool call. */
|
|
66
|
-
export type ToolCall<Name extends string, InputSchema extends
|
|
63
|
+
export type ToolCall<Name extends string, InputSchema extends ToolSchema> = {
|
|
67
64
|
readonly name: Name;
|
|
68
65
|
readonly arguments: Schema.Schema.Type<InputSchema>;
|
|
69
66
|
};
|
|
@@ -75,23 +72,23 @@ export interface ToolPresenter<ServerResult, View extends ViewDefinitionContract
|
|
|
75
72
|
type PresenterView<Presenter> = Presenter extends ToolPresenter<infer _ServerResult, infer View> ? View : never;
|
|
76
73
|
/** View-part union produced by one configured tool. */
|
|
77
74
|
export type ToolViewPart<Presenters extends ReadonlyArray<ToolPresenter<never, ViewDefinitionContract>>> = ViewPart<PresenterView<Presenters[number]>>;
|
|
78
|
-
type ToolModelResult<ModelSchema extends
|
|
75
|
+
type ToolModelResult<ModelSchema extends ToolSchema | undefined> = ModelSchema extends ToolSchema ? Schema.Schema.Type<ModelSchema> : undefined;
|
|
79
76
|
/** Complete trusted result of one parsed and executed tool call. */
|
|
80
|
-
export interface ToolExecution<ServerResult, ModelSchema extends
|
|
77
|
+
export interface ToolExecution<ServerResult, ModelSchema extends ToolSchema | undefined, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>>> {
|
|
81
78
|
readonly serverResult: ServerResult;
|
|
82
79
|
readonly modelResult: ToolModelResult<ModelSchema>;
|
|
83
80
|
readonly views: ReadonlyArray<ToolViewPart<Presenters>>;
|
|
84
81
|
readonly [toolExecutionModelContext]: string | undefined;
|
|
85
82
|
}
|
|
86
|
-
interface ToolModelProjection<ServerResult, ModelSchema extends
|
|
83
|
+
interface ToolModelProjection<ServerResult, ModelSchema extends ToolSchema> {
|
|
87
84
|
readonly schema: ModelSchema;
|
|
88
85
|
readonly project: (result: ServerResult) => Schema.Schema.Type<ModelSchema>;
|
|
89
86
|
}
|
|
90
|
-
interface ToolRuntime<Name extends string, InputSchema extends
|
|
87
|
+
interface ToolRuntime<Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements, ModelSchema extends ToolSchema | undefined, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>>, Operation extends ToolOperation> {
|
|
91
88
|
readonly executeServer: (input: Schema.Schema.Type<InputSchema>, context: Operation extends "command" ? CommandExecutionContext : undefined) => Effect.Effect<ServerResult, Error, Requirements>;
|
|
92
|
-
readonly modelProjection: ModelSchema extends
|
|
89
|
+
readonly modelProjection: ModelSchema extends ToolSchema ? ToolModelProjection<ServerResult, ModelSchema> : undefined;
|
|
93
90
|
readonly presenters: Presenters;
|
|
94
|
-
readonly callSchema:
|
|
91
|
+
readonly callSchema: ToolSchema;
|
|
95
92
|
readonly name: Name;
|
|
96
93
|
readonly description: string;
|
|
97
94
|
readonly inputSchema: InputSchema;
|
|
@@ -105,7 +102,7 @@ interface RuntimeToolExecutionContext {
|
|
|
105
102
|
/** @internal Read the bounded model-visible context retained by one execution. */
|
|
106
103
|
export declare const readToolExecutionModelContext: (execution: RuntimeToolExecutionContext) => string | undefined;
|
|
107
104
|
/** One schema-defined, executable, and pipeable query tool. */
|
|
108
|
-
export interface StructuredTool<Name extends string, InputSchema extends
|
|
105
|
+
export interface StructuredTool<Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements, ModelSchema extends ToolSchema | undefined = undefined, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>> = readonly [], Operation extends ToolOperation = "query"> extends Pipeable.Pipeable, ToolDefinitionContract {
|
|
109
106
|
readonly name: Name;
|
|
110
107
|
readonly operation: Operation;
|
|
111
108
|
readonly inputSchema: InputSchema;
|
|
@@ -120,30 +117,30 @@ export interface StructuredTool<Name extends string, InputSchema extends Schema.
|
|
|
120
117
|
readonly [toolRuntime]: ToolRuntime<Name, InputSchema, ServerResult, Error, Requirements, ModelSchema, Presenters, Operation>;
|
|
121
118
|
}
|
|
122
119
|
/** One side-effecting capability accepted only by a terminal command stage. */
|
|
123
|
-
export type StructuredCommand<Name extends string, InputSchema extends
|
|
120
|
+
export type StructuredCommand<Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements, ModelSchema extends ToolSchema | undefined = undefined, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>> = readonly []> = StructuredTool<Name, InputSchema, ServerResult, Error, Requirements, ModelSchema, Presenters, "command">;
|
|
124
121
|
/** Definition input for one read-only structured chat tool. */
|
|
125
|
-
export interface DefineToolInput<Name extends string, InputSchema extends
|
|
122
|
+
export interface DefineToolInput<Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements> {
|
|
126
123
|
readonly name: Name;
|
|
127
124
|
readonly description: string;
|
|
128
125
|
readonly input: InputSchema;
|
|
129
126
|
readonly execute: (input: Schema.Schema.Type<InputSchema>) => Effect.Effect<ServerResult, Error, Requirements>;
|
|
130
127
|
}
|
|
131
128
|
/** Definition input for one idempotently executed structured command. */
|
|
132
|
-
export interface DefineCommandInput<Name extends string, InputSchema extends
|
|
129
|
+
export interface DefineCommandInput<Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements> {
|
|
133
130
|
readonly name: Name;
|
|
134
131
|
readonly description: string;
|
|
135
132
|
readonly input: InputSchema;
|
|
136
133
|
readonly execute: (input: Schema.Schema.Type<InputSchema>, context: CommandExecutionContext) => Effect.Effect<ServerResult, Error, Requirements>;
|
|
137
134
|
}
|
|
138
135
|
/** Define one read-only, schema-validated structured chat tool. */
|
|
139
|
-
export declare const defineTool: <const Name extends string, InputSchema extends
|
|
136
|
+
export declare const defineTool: <const Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements>(definition: DefineToolInput<Name, InputSchema, ServerResult, Error, Requirements>) => StructuredTool<Name, InputSchema, ServerResult, Error, Requirements>;
|
|
140
137
|
/** Define one side-effecting command requiring a stable idempotency key. */
|
|
141
|
-
export declare const defineCommand: <const Name extends string, InputSchema extends
|
|
138
|
+
export declare const defineCommand: <const Name extends string, InputSchema extends ToolSchema, ServerResult, Error, Requirements>(definition: DefineCommandInput<Name, InputSchema, ServerResult, Error, Requirements>) => StructuredCommand<Name, InputSchema, ServerResult, Error, Requirements>;
|
|
142
139
|
/** Combinators that add optional capabilities to a structured tool. */
|
|
143
140
|
export declare const Tool: {
|
|
144
|
-
readonly modelResult: <ServerResult, ModelSchema extends
|
|
145
|
-
readonly present: <ServerResult, View extends ViewDefinitionContract>(view: View, project: (result: ServerResult) => ViewInput<View> | undefined) => <Name extends string, InputSchema extends
|
|
141
|
+
readonly modelResult: <ServerResult, ModelSchema extends ToolSchema>(schema: ModelSchema, project: (result: ServerResult) => Schema.Schema.Type<ModelSchema>) => <Name extends string, InputSchema extends ToolSchema, Error, Requirements, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>>, Operation extends ToolOperation>(tool: StructuredTool<Name, InputSchema, ServerResult, Error, Requirements, undefined, Presenters, Operation>) => StructuredTool<Name, InputSchema, ServerResult, Error, Requirements, ModelSchema, Presenters, Operation>;
|
|
142
|
+
readonly present: <ServerResult, View extends ViewDefinitionContract>(view: View, project: (result: ServerResult) => ViewInput<View> | undefined) => <Name extends string, InputSchema extends ToolSchema, Error, Requirements, ModelSchema extends ToolSchema | undefined, Presenters extends ReadonlyArray<ToolPresenter<ServerResult, ViewDefinitionContract>>, Operation extends ToolOperation>(tool: StructuredTool<Name, InputSchema, ServerResult, Error, Requirements, ModelSchema, Presenters, Operation>) => StructuredTool<Name, InputSchema, ServerResult, Error, Requirements, ModelSchema, readonly [...Presenters, ToolPresenter<ServerResult, View>], Operation>;
|
|
146
143
|
};
|
|
147
144
|
/** Parse failure retained only for documentation of owned schema boundaries. */
|
|
148
|
-
export type ToolBoundaryParseError =
|
|
145
|
+
export type ToolBoundaryParseError = Schema.SchemaError;
|
|
149
146
|
export {};
|