@copilotkit/shared 1.55.3-canary.1776260990 → 1.56.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/a2ui-prompts.cjs +31 -22
- package/dist/a2ui-prompts.cjs.map +1 -1
- package/dist/a2ui-prompts.d.cts +2 -2
- package/dist/a2ui-prompts.d.cts.map +1 -1
- package/dist/a2ui-prompts.d.mts +2 -2
- package/dist/a2ui-prompts.d.mts.map +1 -1
- package/dist/a2ui-prompts.mjs +31 -22
- package/dist/a2ui-prompts.mjs.map +1 -1
- package/dist/debug.cjs +38 -0
- package/dist/debug.cjs.map +1 -0
- package/dist/debug.d.cts +29 -0
- package/dist/debug.d.cts.map +1 -0
- package/dist/debug.d.mts +29 -0
- package/dist/debug.d.mts.map +1 -0
- package/dist/debug.mjs +37 -0
- package/dist/debug.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +69 -23
- package/dist/index.umd.js.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/package.json +1 -1
- package/src/__tests__/debug.test.ts +116 -0
- package/src/a2ui-prompts.ts +31 -22
- package/src/debug.ts +55 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { resolveDebugConfig } from "../debug";
|
|
3
|
+
|
|
4
|
+
describe("resolveDebugConfig", () => {
|
|
5
|
+
it("returns all-off for undefined", () => {
|
|
6
|
+
expect(resolveDebugConfig(undefined)).toEqual({
|
|
7
|
+
enabled: false,
|
|
8
|
+
events: false,
|
|
9
|
+
lifecycle: false,
|
|
10
|
+
verbose: false,
|
|
11
|
+
});
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("returns all-off for false", () => {
|
|
15
|
+
expect(resolveDebugConfig(false)).toEqual({
|
|
16
|
+
enabled: false,
|
|
17
|
+
events: false,
|
|
18
|
+
lifecycle: false,
|
|
19
|
+
verbose: false,
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("returns events + lifecycle on but verbose off for true (PII safety)", () => {
|
|
24
|
+
expect(resolveDebugConfig(true)).toEqual({
|
|
25
|
+
enabled: true,
|
|
26
|
+
events: true,
|
|
27
|
+
lifecycle: true,
|
|
28
|
+
verbose: false,
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("allows explicit verbose opt-in via object shorthand", () => {
|
|
33
|
+
expect(resolveDebugConfig({ verbose: true })).toEqual({
|
|
34
|
+
enabled: true,
|
|
35
|
+
events: true,
|
|
36
|
+
lifecycle: true,
|
|
37
|
+
verbose: true,
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("allows explicit verbose opt-in with events", () => {
|
|
42
|
+
expect(resolveDebugConfig({ events: true, verbose: true })).toEqual({
|
|
43
|
+
enabled: true,
|
|
44
|
+
events: true,
|
|
45
|
+
lifecycle: true,
|
|
46
|
+
verbose: true,
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("defaults events and lifecycle to true, verbose to false for empty object", () => {
|
|
51
|
+
expect(resolveDebugConfig({})).toEqual({
|
|
52
|
+
enabled: true,
|
|
53
|
+
events: true,
|
|
54
|
+
lifecycle: true,
|
|
55
|
+
verbose: false,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("respects explicit events: true", () => {
|
|
60
|
+
expect(resolveDebugConfig({ events: true })).toEqual({
|
|
61
|
+
enabled: true,
|
|
62
|
+
events: true,
|
|
63
|
+
lifecycle: true,
|
|
64
|
+
verbose: false,
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("respects explicit events: false (lifecycle still defaults true)", () => {
|
|
69
|
+
expect(resolveDebugConfig({ events: false })).toEqual({
|
|
70
|
+
enabled: true,
|
|
71
|
+
events: false,
|
|
72
|
+
lifecycle: true,
|
|
73
|
+
verbose: false,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("respects explicit lifecycle: false (events still defaults true)", () => {
|
|
78
|
+
expect(resolveDebugConfig({ lifecycle: false })).toEqual({
|
|
79
|
+
enabled: true,
|
|
80
|
+
events: true,
|
|
81
|
+
lifecycle: false,
|
|
82
|
+
verbose: false,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("sets enabled to false when both events and lifecycle are false", () => {
|
|
87
|
+
expect(resolveDebugConfig({ events: false, lifecycle: false })).toEqual({
|
|
88
|
+
enabled: false,
|
|
89
|
+
events: false,
|
|
90
|
+
lifecycle: false,
|
|
91
|
+
verbose: false,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("clamps verbose to false when enabled is false (events and lifecycle both false)", () => {
|
|
96
|
+
expect(
|
|
97
|
+
resolveDebugConfig({ events: false, lifecycle: false, verbose: true }),
|
|
98
|
+
).toEqual({
|
|
99
|
+
enabled: false,
|
|
100
|
+
events: false,
|
|
101
|
+
lifecycle: false,
|
|
102
|
+
verbose: false,
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it("handles mixed config: events true, lifecycle false, verbose true", () => {
|
|
107
|
+
expect(
|
|
108
|
+
resolveDebugConfig({ events: true, lifecycle: false, verbose: true }),
|
|
109
|
+
).toEqual({
|
|
110
|
+
enabled: true,
|
|
111
|
+
events: true,
|
|
112
|
+
lifecycle: false,
|
|
113
|
+
verbose: true,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
package/src/a2ui-prompts.ts
CHANGED
|
@@ -47,29 +47,38 @@ CRITICAL: Do NOT use "/name" (absolute) inside templates — use "name" (relativ
|
|
|
47
47
|
The container's path ("/items") uses a leading slash (absolute), but all
|
|
48
48
|
components INSIDE the template use paths WITHOUT leading slash.
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
COMPONENT VALUES — DEFAULT RULE:
|
|
51
|
+
Use inline literal values for ALL component properties. Pass strings, numbers,
|
|
52
|
+
arrays, and objects directly on the component. Do NOT use { "path": "..." }
|
|
53
|
+
objects unless the property's schema explicitly allows it (see exception below).
|
|
54
|
+
CRITICAL: USING { "path": "..." } ON A PROPERTY THAT DOES NOT DECLARE PATH
|
|
55
|
+
SUPPORT IN ITS SCHEMA WILL CAUSE A RUNTIME CRASH AND BREAK THE ENTIRE UI.
|
|
56
|
+
ALWAYS CHECK THE COMPONENT SCHEMA FIRST — IF THE PROPERTY ONLY ACCEPTS A
|
|
57
|
+
PLAIN TYPE, YOU MUST USE A LITERAL VALUE.
|
|
58
|
+
VERY IMPORTANT: THE APPLICATION WILL BREAK IF YOU DO NOT FOLLOW THIS RULE!
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
You MUST use { "path": "..." } to make inputs editable.
|
|
60
|
+
For example, a chart's "data" must always be an inline array:
|
|
61
|
+
"data": [{"label": "Jan", "value": 100}, {"label": "Feb", "value": 200}]
|
|
62
|
+
A metric's "value" must always be an inline string:
|
|
63
|
+
"value": "$1,200"
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
PATH BINDING EXCEPTION — SCHEMA-DRIVEN:
|
|
66
|
+
A few properties accept { "path": "/some/path" } as an alternative to a literal
|
|
67
|
+
value. You can identify these in the Available Components schema: the property
|
|
68
|
+
will list BOTH a literal type AND an object-with-path option. If a property only
|
|
69
|
+
shows a single type (string, number, array, etc.), it does NOT support path
|
|
70
|
+
binding — use a literal value only.
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
Path binding is typically used for editable form inputs so the client can write
|
|
73
|
+
user input back to the data model. When building forms:
|
|
74
|
+
- Bind input "value" to a data model path: "value": { "path": "/form/name" }
|
|
75
|
+
- Pre-fill via the "data" tool argument: "data": { "form": { "name": "Alice" } }
|
|
76
|
+
- Capture values on submit via button action context:
|
|
77
|
+
"action": { "event": { "name": "submit", "context": { "name": { "path": "/form/name" } } } }
|
|
70
78
|
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
REPEATING CONTENT uses a structural children format (not the same as value binding):
|
|
80
|
+
children: { componentId: "card-id", path: "/items" }
|
|
81
|
+
Components inside templates use RELATIVE paths (no leading slash): { "path": "name" }.`;
|
|
73
82
|
|
|
74
83
|
/**
|
|
75
84
|
* Design guidelines — visual design rules, component hierarchy tips,
|
|
@@ -94,8 +103,8 @@ Design principles:
|
|
|
94
103
|
"action": { "event": { "name": "myAction", "context": { "key": "value" } } }
|
|
95
104
|
The "event" key holds an OBJECT with "name" (required) and "context" (optional).
|
|
96
105
|
Do NOT use a flat format like {"event": "name"} — "event" must be an object.
|
|
97
|
-
- For forms:
|
|
98
|
-
|
|
99
|
-
action context
|
|
106
|
+
- For forms: check the component schema — if an input's "value" property
|
|
107
|
+
supports path binding, use it for editable fields. The submit button's
|
|
108
|
+
action context should reference the same paths to capture user input.
|
|
100
109
|
|
|
101
110
|
Use the SAME surfaceId as the main surface. Match action names to button action event names.`;
|
package/src/debug.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Granular debug configuration for CopilotKit runtime and client.
|
|
3
|
+
* Pass `true` to enable events + lifecycle logging (but NOT verbose payloads),
|
|
4
|
+
* or an object for granular control including `verbose: true` for full payloads.
|
|
5
|
+
*/
|
|
6
|
+
export type DebugConfig =
|
|
7
|
+
| boolean
|
|
8
|
+
| {
|
|
9
|
+
/** Log every event emitted/received. Default: true */
|
|
10
|
+
events?: boolean;
|
|
11
|
+
/** Log request/run lifecycle. Default: true */
|
|
12
|
+
lifecycle?: boolean;
|
|
13
|
+
/** Log full event payloads instead of summaries. Default: false — must be explicitly opted in */
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** Normalized debug configuration — all fields resolved to booleans. */
|
|
18
|
+
export interface ResolvedDebugConfig {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
events: boolean;
|
|
21
|
+
lifecycle: boolean;
|
|
22
|
+
verbose: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** The all-off config used when debug is falsy. */
|
|
26
|
+
const DEBUG_OFF: ResolvedDebugConfig = {
|
|
27
|
+
enabled: false,
|
|
28
|
+
events: false,
|
|
29
|
+
lifecycle: false,
|
|
30
|
+
verbose: false,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Normalizes a DebugConfig value into a ResolvedDebugConfig.
|
|
35
|
+
*
|
|
36
|
+
* - `false` / `undefined` → all off
|
|
37
|
+
* - `true` → events + lifecycle on, verbose off (no PII in logs)
|
|
38
|
+
* - object → merges with defaults (events: true, lifecycle: true, verbose: false)
|
|
39
|
+
*/
|
|
40
|
+
export function resolveDebugConfig(
|
|
41
|
+
debug: DebugConfig | undefined,
|
|
42
|
+
): ResolvedDebugConfig {
|
|
43
|
+
if (!debug) return DEBUG_OFF;
|
|
44
|
+
|
|
45
|
+
if (debug === true) {
|
|
46
|
+
return { enabled: true, events: true, lifecycle: true, verbose: false };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const events = debug.events ?? true;
|
|
50
|
+
const lifecycle = debug.lifecycle ?? true;
|
|
51
|
+
const enabled = events || lifecycle;
|
|
52
|
+
const verbose = enabled && (debug.verbose ?? false);
|
|
53
|
+
|
|
54
|
+
return { enabled, events, lifecycle, verbose };
|
|
55
|
+
}
|