@copilotkit/channels-core 0.10.0 → 0.11.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/dist/index.d.ts CHANGED
@@ -23,6 +23,8 @@ export { Transcripts } from "./transcripts.js";
23
23
  export type { TranscriptEntry, TranscriptsConfig } from "./transcripts.js";
24
24
  export { toAgentToolDescriptors, parseToolArgs, stringifyHandlerResult, defineChannelTool, } from "./tools.js";
25
25
  export type { ChannelTool, ObjectSchema, ChannelToolContext, ContextEntry, AgentToolDescriptor, } from "./tools.js";
26
+ export { singleStringParameterSchema } from "./standard-schema.js";
27
+ export type { SingleStringParameterSchema } from "./standard-schema.js";
26
28
  export { mintId, stableStringify } from "./mint-id.js";
27
29
  export { runAgentLoop } from "./run-loop.js";
28
30
  export type { RunLoopArgs } from "./run-loop.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -30,6 +30,10 @@ export { createStateBackedConversationStore } from "./state/state-conversation-s
30
30
  export { Transcripts } from "./transcripts.js";
31
31
  // Tools & context
32
32
  export { toAgentToolDescriptors, parseToolArgs, stringifyHandlerResult, defineChannelTool, } from "./tools.js";
33
+ // Parameter-schema builder for the `lookup_<platform>_user` tool every
34
+ // adapter ships. Lets an adapter describe a one-string parameter without
35
+ // declaring `zod` (PE-30) — see `standard-schema.ts` for why that matters.
36
+ export { singleStringParameterSchema } from "./standard-schema.js";
33
37
  // Id / serialization helpers
34
38
  export { mintId, stableStringify } from "./mint-id.js";
35
39
  // Run loop
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=single-string-parameter-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-string-parameter-schema.test.d.ts","sourceRoot":"","sources":["../src/single-string-parameter-schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * `singleStringParameterSchema` replaces the `z.object({query: z.string()
3
+ * .min(1).describe(...)})` that every platform adapter used to build its
4
+ * `lookup_<platform>_user` parameter with, so that no adapter declares a
5
+ * `zod` range (PE-30).
6
+ *
7
+ * The contract it has to honor is "behaves like the Zod object it replaces",
8
+ * so these tests assert against Zod itself rather than against a transcribed
9
+ * expectation. `zod` is a devDependency of this package; nothing published
10
+ * imports it.
11
+ */
12
+ import { describe, it, expect } from "vitest";
13
+ import { z } from "zod";
14
+ import { zodToJsonSchema } from "zod-to-json-schema";
15
+ import { singleStringParameterSchema } from "./standard-schema.js";
16
+ import { toJsonSchema, validateSchema } from "./standard-schema.js";
17
+ const DESCRIPTION = "Handle, display name, or first name of the person.";
18
+ const schema = singleStringParameterSchema({
19
+ name: "query",
20
+ description: DESCRIPTION,
21
+ });
22
+ /** The exact Zod object this helper is a drop-in replacement for. */
23
+ const zodEquivalent = z.object({
24
+ query: z.string().min(1).describe(DESCRIPTION),
25
+ });
26
+ describe("singleStringParameterSchema", () => {
27
+ it("emits the JSON Schema document the Zod object emits", () => {
28
+ expect(toJsonSchema(schema)).toEqual(zodToJsonSchema(zodEquivalent, { $refStrategy: "none" }));
29
+ });
30
+ it("names the field the caller asked for", () => {
31
+ const renamed = singleStringParameterSchema({
32
+ name: "handle",
33
+ description: DESCRIPTION,
34
+ });
35
+ const doc = toJsonSchema(renamed);
36
+ expect(Object.keys(doc.properties)).toEqual(["handle"]);
37
+ expect(doc.required).toEqual(["handle"]);
38
+ });
39
+ it("names this package as the vendor, not zod and not the caller", () => {
40
+ // The Standard Schema `vendor` names the library that produced the
41
+ // schema, which is `channels-core` whichever adapter calls the helper.
42
+ // It also has to not be "zod": `schemaToJsonSchema` routes a
43
+ // `vendor: "zod"` schema through `zod-to-json-schema`, and anything else
44
+ // must carry its own document.
45
+ expect(schema["~standard"].vendor).toBe("@copilotkit/channels-core");
46
+ const renamed = singleStringParameterSchema({
47
+ name: "handle",
48
+ description: DESCRIPTION,
49
+ });
50
+ expect(renamed["~standard"].vendor).toBe("@copilotkit/channels-core");
51
+ });
52
+ it("accepts a valid value, exactly as the Zod object does", async () => {
53
+ expect(await validateSchema(schema, { query: "ada" })).toEqual({
54
+ ok: true,
55
+ value: { query: "ada" },
56
+ });
57
+ expect(zodEquivalent.safeParse({ query: "ada" }).data).toEqual({
58
+ query: "ada",
59
+ });
60
+ });
61
+ it("strips unknown keys rather than rejecting them, as z.object does", async () => {
62
+ const input = { query: "ada", extra: "ignored" };
63
+ expect(await validateSchema(schema, input)).toEqual({
64
+ ok: true,
65
+ value: { query: "ada" },
66
+ });
67
+ // Pin the Zod behavior this mirrors, so a Zod default change is visible.
68
+ expect(zodEquivalent.safeParse(input).data).toEqual({ query: "ada" });
69
+ });
70
+ it("rejects a missing field and names it", async () => {
71
+ const r = await validateSchema(schema, {});
72
+ expect(r.ok).toBe(false);
73
+ expect(r.ok === false && r.error).toContain("query");
74
+ expect(zodEquivalent.safeParse({}).success).toBe(false);
75
+ });
76
+ it("rejects an empty string, which is what .min(1) guarded", async () => {
77
+ const r = await validateSchema(schema, { query: "" });
78
+ expect(r.ok).toBe(false);
79
+ expect(zodEquivalent.safeParse({ query: "" }).success).toBe(false);
80
+ });
81
+ it.each([
82
+ ["a number", 42, "number"],
83
+ ["null", null, "null"],
84
+ ["an array", [], "array"],
85
+ ])("rejects %s field, naming the received type", async (_label, value, received) => {
86
+ const r = await validateSchema(schema, { query: value });
87
+ expect(r.ok).toBe(false);
88
+ expect(r.ok === false && r.error).toContain(received);
89
+ });
90
+ it.each([
91
+ ["null", null],
92
+ ["an array", []],
93
+ ["a string", "ada"],
94
+ ])("rejects %s as the whole argument payload", async (_label, value) => {
95
+ const r = await validateSchema(schema, value);
96
+ expect(r.ok).toBe(false);
97
+ expect(zodEquivalent.safeParse(value).success).toBe(false);
98
+ });
99
+ /**
100
+ * The error string is what the agent reads back on a bad tool call, so it
101
+ * is part of the contract, not an implementation detail. Asserting only
102
+ * "both reject" let a real divergence through: a missing field reported
103
+ * "Expected string, received undefined" where Zod reports "Required".
104
+ * Compare the rendered text, formatted the same way `validateSchema` does.
105
+ */
106
+ it.each([
107
+ ["a missing field", {}],
108
+ ["a number field", { query: 42 }],
109
+ ["a null field", { query: null }],
110
+ ["an array field", { query: [] }],
111
+ ["a boolean field", { query: true }],
112
+ ["an object field", { query: {} }],
113
+ ["an explicit undefined field", { query: undefined }],
114
+ ["an empty string", { query: "" }],
115
+ ["null as the payload", null],
116
+ ["an array as the payload", []],
117
+ ["a string as the payload", "ada"],
118
+ ["a number as the payload", 7],
119
+ ])("renders the same error text as zod for %s", async (_label, value) => {
120
+ const mine = await validateSchema(schema, value);
121
+ const theirs = zodEquivalent.safeParse(value);
122
+ expect(mine.ok).toBe(theirs.success);
123
+ expect(theirs.success).toBe(false);
124
+ const zodText = theirs.success
125
+ ? null
126
+ : theirs.error.issues
127
+ .map((i) => `${i.path.join(".") || "(root)"}: ${i.message}`)
128
+ .join("; ");
129
+ expect(mine.ok === false && mine.error).toBe(zodText);
130
+ });
131
+ /**
132
+ * `zodToJsonSchema` built a fresh document on every call and
133
+ * `toAgentToolDescriptors` hands its result straight to the caller, so a
134
+ * consumer that normalizes the schema in place (dropping `$schema` for a
135
+ * provider that rejects it, for instance) must not corrupt later turns.
136
+ */
137
+ it("returns a fresh JSON Schema document on every call", () => {
138
+ const first = toJsonSchema(schema);
139
+ const second = toJsonSchema(schema);
140
+ expect(first).not.toBe(second);
141
+ expect(first).toEqual(second);
142
+ first.properties.query.description = "mutated by a consumer";
143
+ const third = toJsonSchema(schema);
144
+ expect(third.properties.query.description).toBe(DESCRIPTION);
145
+ });
146
+ });
147
+ /**
148
+ * Type-level assertions. `check-types` runs `tsconfig.check.json`, which
149
+ * includes this file, so a `@ts-expect-error` here fails the build when the
150
+ * error it expects stops happening. Nothing below runs.
151
+ *
152
+ * The output type is built by mapping over `Name`. A union of names would
153
+ * claim every member is a present `string` while the function creates exactly
154
+ * one key, and a widened `string` would claim every possible key. Both promise
155
+ * a `string` where the value is `undefined`, so both have to be rejected at
156
+ * the call.
157
+ */
158
+ describe("type-level contract", () => {
159
+ it("is enforced by check-types, not at runtime", () => {
160
+ const literal = singleStringParameterSchema({
161
+ name: "query",
162
+ description: DESCRIPTION,
163
+ });
164
+ // The literal key is inferred, and nothing else exists on the output.
165
+ const ok = { query: "ada" };
166
+ // @ts-expect-error `nope` is not a key of the inferred output
167
+ const bogus = { query: "ada", nope: 1 };
168
+ const unionName = (Math.random() > 0.5 ? "query" : "handle");
169
+ singleStringParameterSchema({
170
+ // @ts-expect-error a union of names would promise a key that is never created
171
+ name: unionName,
172
+ description: DESCRIPTION,
173
+ });
174
+ const dynamicName = "query";
175
+ singleStringParameterSchema({
176
+ // @ts-expect-error a widened `string` would promise every possible key
177
+ name: dynamicName,
178
+ description: DESCRIPTION,
179
+ });
180
+ expect(ok.query).toBe("ada");
181
+ expect(bogus).toBeDefined();
182
+ });
183
+ });
@@ -1,5 +1,5 @@
1
- import type { StandardSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
2
- export type { StandardSchemaV1, InferSchemaOutput };
1
+ import type { StandardSchemaV1, StandardJSONSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
2
+ export type { StandardSchemaV1, StandardJSONSchemaV1, InferSchemaOutput };
3
3
  /**
4
4
  * A Standard Schema whose validated output is an object record.
5
5
  *
@@ -35,4 +35,79 @@ export type SchemaParseResult<T> = {
35
35
  * a JSON tool result so the agent can recover from a bad tool call.
36
36
  */
37
37
  export declare function validateSchema<S extends StandardSchemaV1>(schema: S, value: unknown): Promise<SchemaParseResult<InferSchemaOutput<S>>>;
38
+ /** True when `T` is a union of more than one member. */
39
+ type IsUnion<T, U = T> = T extends unknown ? [U] extends [T] ? false : true : never;
40
+ /**
41
+ * `Name` unless it is a union or the widened `string`, in which case `never`.
42
+ *
43
+ * The output type is built by mapping over `Name`, so a union claims every
44
+ * member is present while the function creates exactly one key, and a widened
45
+ * `string` claims every possible key. Either way the type promises a `string`
46
+ * where the value is `undefined`. Restricting the parameter to one literal is
47
+ * what makes `SingleStringParameterSchema` honest.
48
+ */
49
+ type SingleLiteral<Name extends string> = string extends Name ? never : true extends IsUnion<Name> ? never : Name;
50
+ /**
51
+ * A parameter schema for a tool that takes exactly one required string.
52
+ *
53
+ * The output type is keyed by the literal `Name` passed in, so a handler
54
+ * written against it destructures the real field name and not a widened
55
+ * `Record`.
56
+ */
57
+ export type SingleStringParameterSchema<Name extends string> = StandardSchemaV1<unknown, {
58
+ [K in Name]: string;
59
+ }> & StandardJSONSchemaV1<unknown, {
60
+ [K in Name]: string;
61
+ }>;
62
+ /**
63
+ * Build a tool parameter schema for a single required, non-empty string,
64
+ * written directly against the [Standard Schema](https://standardschema.dev)
65
+ * protocol.
66
+ *
67
+ * WHY THIS EXISTS (PE-30, OSS-1173)
68
+ * ---------------------------------
69
+ * Every platform adapter ships one `lookup_<platform>_user` tool, and each
70
+ * one took the same parameter: a single string to resolve to a user. Each
71
+ * built that parameter with `z.object({query: z.string().min(1)})`, and a
72
+ * `zod` range in the adapter's `package.json` was the price.
73
+ *
74
+ * That price was not local. The `@copilotkit/channels` umbrella depends on
75
+ * every adapter, and `@microsoft/agents-hosting` and
76
+ * `@microsoft/agents-activity` pin `zod` at exactly `3.25.75`. An adapter
77
+ * asking for `^3.25.76` is a range that excludes that pin, so installing the
78
+ * umbrella alongside the Microsoft packages left a tree no application could
79
+ * repair from its own `package.json` — the conflict came from two packages we
80
+ * publish. One dependency for one object literal was not a trade worth
81
+ * keeping, three times over.
82
+ *
83
+ * `defineChannelTool` accepts any Standard Schema, and `toJsonSchema()` reads
84
+ * `~standard.jsonSchema.input()` in preference to every other path, so this
85
+ * one small object is all a tool ever needed.
86
+ *
87
+ * Behavior mirrors the `z.object({[name]: z.string().min(1).describe(...)})`
88
+ * it replaces: the field is required, must be a string of at least one
89
+ * character, and unknown keys are stripped rather than rejected (Zod's
90
+ * default `strip` mode for `z.object`). The emitted document is what
91
+ * `zod-to-json-schema` emitted for that object, so the descriptor the model
92
+ * is shown does not change. Its body is target-agnostic — `type`,
93
+ * `properties`, `required`, `minLength` and `additionalProperties` mean the
94
+ * same thing in draft-07 and draft-2020-12 — so one document serves every
95
+ * target a caller asks for, and `$schema` keeps the draft-07 value the
96
+ * previous output carried.
97
+ *
98
+ * The one-character floor is fixed rather than configurable because all three
99
+ * call sites want it and a knob nobody turns is a knob nobody tests.
100
+ */
101
+ export declare function singleStringParameterSchema<const Name extends string>(options: {
102
+ /**
103
+ * Field name, e.g. `"query"`. Becomes the sole key of the output object.
104
+ *
105
+ * Must be a single string literal. A union or a widened `string` is a
106
+ * compile error, because the output type would then promise keys this
107
+ * function never creates. See `SingleLiteral`.
108
+ */
109
+ name: SingleLiteral<Name>;
110
+ /** Field description handed to the model. Was `z.string().describe(...)`. */
111
+ description: string;
112
+ }): SingleStringParameterSchema<Name>;
38
113
  //# sourceMappingURL=standard-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG9E,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;AAEpD;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWzB;AAED,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,gBAAgB,EAC7D,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAWlD"}
1
+ {"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../src/standard-schema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;AAE1E;;;;;;;;;GASG;AACH,MAAM,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWzB;AAED,4EAA4E;AAC5E,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,CAAC,SAAS,gBAAgB,EAC7D,MAAM,EAAE,CAAC,EACT,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAWlD;AAwBD,wDAAwD;AACxD,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,GACtC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GACb,KAAK,GACL,IAAI,GACN,KAAK,CAAC;AAEV;;;;;;;;GAQG;AACH,KAAK,aAAa,CAAC,IAAI,SAAS,MAAM,IAAI,MAAM,SAAS,IAAI,GACzD,KAAK,GACL,IAAI,SAAS,OAAO,CAAC,IAAI,CAAC,GACxB,KAAK,GACL,IAAI,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,2BAA2B,CAAC,IAAI,SAAS,MAAM,IAAI,gBAAgB,CAC7E,OAAO,EACP;KAAG,CAAC,IAAI,IAAI,GAAG,MAAM;CAAE,CACxB,GACC,oBAAoB,CAAC,OAAO,EAAE;KAAG,CAAC,IAAI,IAAI,GAAG,MAAM;CAAE,CAAC,CAAC;AAazD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,CAAC,IAAI,SAAS,MAAM,EACzB,OAAO,EAAE;IACT;;;;;;OAMG;IACH,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,2BAA2B,CAAC,IAAI,CAAC,CA6EpC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Schema-library-agnostic helpers for the Slack SDK.
2
+ * Schema-library-agnostic helpers for the Channels SDK.
3
3
  *
4
4
  * The public API accepts any [Standard Schema](https://standardschema.dev)
5
5
  * validator — Zod 3.24+, Valibot v1+, ArkType v2+, and anything else that
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * These wrap the canonical primitives from `@copilotkit/shared` (the same
12
12
  * ones `@copilotkit/core` uses for its `FrontendTool` parameters) plus a
13
- * couple of Slack-local conveniences.
13
+ * couple of Channels-local conveniences.
14
14
  */
15
15
  import { schemaToJsonSchema as sharedSchemaToJsonSchema } from "@copilotkit/shared";
16
16
  import { zodToJsonSchema } from "zod-to-json-schema";
@@ -64,3 +64,128 @@ function formatIssues(issues) {
64
64
  })
65
65
  .join("; ");
66
66
  }
67
+ /**
68
+ * `typeof` reports "object" for both `null` and arrays. Zod names them
69
+ * separately, and this message is what the agent reads back on a bad call,
70
+ * so it is worth the three lines to keep the wording it used to get.
71
+ */
72
+ function parsedTypeOf(value) {
73
+ if (value === null)
74
+ return "null";
75
+ if (Array.isArray(value))
76
+ return "array";
77
+ return typeof value;
78
+ }
79
+ /**
80
+ * Build a tool parameter schema for a single required, non-empty string,
81
+ * written directly against the [Standard Schema](https://standardschema.dev)
82
+ * protocol.
83
+ *
84
+ * WHY THIS EXISTS (PE-30, OSS-1173)
85
+ * ---------------------------------
86
+ * Every platform adapter ships one `lookup_<platform>_user` tool, and each
87
+ * one took the same parameter: a single string to resolve to a user. Each
88
+ * built that parameter with `z.object({query: z.string().min(1)})`, and a
89
+ * `zod` range in the adapter's `package.json` was the price.
90
+ *
91
+ * That price was not local. The `@copilotkit/channels` umbrella depends on
92
+ * every adapter, and `@microsoft/agents-hosting` and
93
+ * `@microsoft/agents-activity` pin `zod` at exactly `3.25.75`. An adapter
94
+ * asking for `^3.25.76` is a range that excludes that pin, so installing the
95
+ * umbrella alongside the Microsoft packages left a tree no application could
96
+ * repair from its own `package.json` — the conflict came from two packages we
97
+ * publish. One dependency for one object literal was not a trade worth
98
+ * keeping, three times over.
99
+ *
100
+ * `defineChannelTool` accepts any Standard Schema, and `toJsonSchema()` reads
101
+ * `~standard.jsonSchema.input()` in preference to every other path, so this
102
+ * one small object is all a tool ever needed.
103
+ *
104
+ * Behavior mirrors the `z.object({[name]: z.string().min(1).describe(...)})`
105
+ * it replaces: the field is required, must be a string of at least one
106
+ * character, and unknown keys are stripped rather than rejected (Zod's
107
+ * default `strip` mode for `z.object`). The emitted document is what
108
+ * `zod-to-json-schema` emitted for that object, so the descriptor the model
109
+ * is shown does not change. Its body is target-agnostic — `type`,
110
+ * `properties`, `required`, `minLength` and `additionalProperties` mean the
111
+ * same thing in draft-07 and draft-2020-12 — so one document serves every
112
+ * target a caller asks for, and `$schema` keeps the draft-07 value the
113
+ * previous output carried.
114
+ *
115
+ * The one-character floor is fixed rather than configurable because all three
116
+ * call sites want it and a knob nobody turns is a knob nobody tests.
117
+ */
118
+ export function singleStringParameterSchema(options) {
119
+ // `SingleLiteral<Name>` is a deferred conditional type, so TypeScript cannot
120
+ // prove it reduces to `Name` inside the body. It does for every value that
121
+ // reaches here, because any other value is a compile error at the call.
122
+ const { name, description } = options;
123
+ // Built per call, never shared. `zodToJsonSchema` returned a fresh document
124
+ // every time, and `toAgentToolDescriptors` hands its result straight to the
125
+ // caller. A single shared object would let one consumer's in-place edit —
126
+ // stripping `$schema` for a provider that rejects it, say — silently change
127
+ // what every later turn in the process is shown.
128
+ const buildJsonSchema = () => ({
129
+ type: "object",
130
+ properties: {
131
+ [name]: { type: "string", minLength: 1, description },
132
+ },
133
+ required: [name],
134
+ additionalProperties: false,
135
+ $schema: "http://json-schema.org/draft-07/schema#",
136
+ });
137
+ function validate(value) {
138
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
139
+ return {
140
+ issues: [
141
+ { message: "Expected object, received " + parsedTypeOf(value) },
142
+ ],
143
+ };
144
+ }
145
+ const field = value[name];
146
+ // Zod reports a missing required key as "Required", not as a type
147
+ // mismatch against `undefined`. The agent reads this back when it calls
148
+ // the tool with no argument, which is the most common bad call there is.
149
+ if (field === undefined) {
150
+ return { issues: [{ message: "Required", path: [name] }] };
151
+ }
152
+ if (typeof field !== "string") {
153
+ return {
154
+ issues: [
155
+ {
156
+ message: "Expected string, received " + parsedTypeOf(field),
157
+ path: [name],
158
+ },
159
+ ],
160
+ };
161
+ }
162
+ if (field.length < 1) {
163
+ return {
164
+ issues: [
165
+ {
166
+ message: "String must contain at least 1 character(s)",
167
+ path: [name],
168
+ },
169
+ ],
170
+ };
171
+ }
172
+ // Rebuilt rather than returned as-is: this is what strips unknown keys.
173
+ return { value: { [name]: field } };
174
+ }
175
+ return {
176
+ "~standard": {
177
+ version: 1,
178
+ // The Standard Schema `vendor` names the library that produced the
179
+ // schema, and that library is this one whichever adapter calls it.
180
+ // Consumers branch on this tag — `isZodSchema` in `@copilotkit/runtime`
181
+ // is one — so three different tags for one implementation would be three
182
+ // things to teach such a branch about.
183
+ vendor: "@copilotkit/channels-core",
184
+ validate,
185
+ jsonSchema: {
186
+ input: buildJsonSchema,
187
+ output: buildJsonSchema,
188
+ },
189
+ },
190
+ };
191
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotkit/channels-core",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Platform-agnostic JSX channel engine for CopilotKit (createChannel, Thread, PlatformAdapter, ActionStore).",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -51,9 +51,9 @@
51
51
  "@ag-ui/client": "0.0.59",
52
52
  "@ag-ui/core": "0.0.59",
53
53
  "zod-to-json-schema": "^3.24.1",
54
- "@copilotkit/channels-ui": "~0.10.0",
55
- "@copilotkit/core": "^1.71.2",
56
- "@copilotkit/shared": "^1.71.2"
54
+ "@copilotkit/core": "^1.73.1",
55
+ "@copilotkit/channels-ui": "~0.11.0",
56
+ "@copilotkit/shared": "^1.73.1"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@types/node": "^22.10.0",