@kazzle/app 0.1.726 → 0.1.727
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/client.js
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
// app via the injected `KAZZLE_APP_COMPONENT_<NAME>_URL` env var. That URL
|
|
13
13
|
// is server-to-server only — never expose it to the browser.
|
|
14
14
|
//
|
|
15
|
+
// For thread vs Tools API branching, read `Kazzle-Tool-Context` via
|
|
16
|
+
// `toolContext(req)` from `@kazzle/app/tools` (not this module).
|
|
17
|
+
//
|
|
15
18
|
// Dependency-free on purpose (uses global fetch). Do not add zod/vite here.
|
|
16
19
|
/** Read the injected base URL of the Kazzle API for install-secret calls. */
|
|
17
20
|
export function kazzleApiUrl() {
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
+
/** Header Kazzle sets on every dispatched app-tool HTTP request. Source of truth: shared/tools/tool-invocation.types.ts */
|
|
3
|
+
export declare const TOOL_CONTEXT_HEADER = "Kazzle-Tool-Context";
|
|
4
|
+
export declare const ToolInvocationSource: {
|
|
5
|
+
readonly THREAD: "thread";
|
|
6
|
+
readonly API: "api";
|
|
7
|
+
};
|
|
8
|
+
export type ToolInvocationSource = typeof ToolInvocationSource[keyof typeof ToolInvocationSource];
|
|
9
|
+
/** How this tool call was invoked — thread (AI / resume) vs Tools API. */
|
|
10
|
+
export type ToolInvocationContext = {
|
|
11
|
+
source: typeof ToolInvocationSource.THREAD;
|
|
12
|
+
threadId: string;
|
|
13
|
+
} | {
|
|
14
|
+
source: typeof ToolInvocationSource.API;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Read `Kazzle-Tool-Context` from an incoming tool handler request.
|
|
18
|
+
* Throws when the header is missing or malformed — only Kazzle dispatch should call the route.
|
|
19
|
+
*/
|
|
20
|
+
export declare function toolContext(req: Request): ToolInvocationContext;
|
|
21
|
+
export declare function isThreadToolInvocation(context: ToolInvocationContext): context is Extract<ToolInvocationContext, {
|
|
22
|
+
source: typeof ToolInvocationSource.THREAD;
|
|
23
|
+
}>;
|
|
2
24
|
/** Zod schema for a tool's input object. Use .default(), .optional(), .transform(), etc. */
|
|
3
25
|
export type KazzleToolInputSchema = z.ZodType<Record<string, unknown>>;
|
|
4
26
|
export type ToolRequestMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
@@ -19,7 +41,7 @@ export type KazzleTarget = ({
|
|
|
19
41
|
type: 'kazzle';
|
|
20
42
|
name: string;
|
|
21
43
|
};
|
|
22
|
-
export interface
|
|
44
|
+
export interface ToolActionButtonElement {
|
|
23
45
|
type: 'button';
|
|
24
46
|
id: string;
|
|
25
47
|
label: string;
|
|
@@ -34,21 +56,27 @@ export interface ToolInputButtonElement {
|
|
|
34
56
|
variant?: 'primary' | 'secondary' | 'destructive';
|
|
35
57
|
}
|
|
36
58
|
/**
|
|
37
|
-
* A
|
|
59
|
+
* A required-action card element. Only buttons are rendered today; this stays a
|
|
38
60
|
* union so form controls can be added later alongside their renderer.
|
|
39
61
|
*/
|
|
40
|
-
export type
|
|
41
|
-
export interface
|
|
42
|
-
|
|
62
|
+
export type ToolActionElement = ToolActionButtonElement;
|
|
63
|
+
export interface ToolActionAssignee {
|
|
64
|
+
computerId?: string;
|
|
65
|
+
userId?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface ToolActionSpec {
|
|
43
68
|
title: string;
|
|
44
69
|
description?: string;
|
|
45
|
-
elements:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
70
|
+
elements: ToolActionElement[];
|
|
71
|
+
assignee?: ToolActionAssignee;
|
|
72
|
+
timeoutMs?: number;
|
|
73
|
+
}
|
|
74
|
+
export interface KazzleRequiredAction {
|
|
75
|
+
type: 'action_required';
|
|
76
|
+
title: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
elements: ToolActionElement[];
|
|
79
|
+
assignee?: ToolActionAssignee;
|
|
52
80
|
timeoutMs?: number;
|
|
53
81
|
}
|
|
54
82
|
interface KazzleToolBase {
|
package/dist/tools.js
CHANGED
|
@@ -16,6 +16,54 @@
|
|
|
16
16
|
// server/apps/apps.skills.tools.ts — it reads the SAME shape defined here
|
|
17
17
|
// (`name`, `displayName`, `description`, `input`, `target`).
|
|
18
18
|
// If you change this contract, update that compiler and its tests together.
|
|
19
|
+
//
|
|
20
|
+
// Tool handlers (POST /tools/...) receive:
|
|
21
|
+
// - `Authorization: Bearer <install identity>` — scope secrets via KazzleInstallClient
|
|
22
|
+
// - `Kazzle-Tool-Context: <json>` — thread vs Tools API (`toolContext(req)`)
|
|
23
|
+
// Handlers may return plain text, `{ content }`, or `{ type: "action_required", ... }`
|
|
24
|
+
// to pause the thread until the user acts (see documents/tool-required-action.md).
|
|
25
|
+
// Set `assignee.computerId` when only a specific device may fulfill the card.
|
|
26
|
+
/** Header Kazzle sets on every dispatched app-tool HTTP request. Source of truth: shared/tools/tool-invocation.types.ts */
|
|
27
|
+
export const TOOL_CONTEXT_HEADER = 'Kazzle-Tool-Context';
|
|
28
|
+
export const ToolInvocationSource = {
|
|
29
|
+
THREAD: 'thread',
|
|
30
|
+
API: 'api',
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Read `Kazzle-Tool-Context` from an incoming tool handler request.
|
|
34
|
+
* Throws when the header is missing or malformed — only Kazzle dispatch should call the route.
|
|
35
|
+
*/
|
|
36
|
+
export function toolContext(req) {
|
|
37
|
+
const raw = req.headers.get(TOOL_CONTEXT_HEADER);
|
|
38
|
+
if (!raw) {
|
|
39
|
+
throw new Error(`Missing ${TOOL_CONTEXT_HEADER} header — expected a Kazzle tool dispatch.`);
|
|
40
|
+
}
|
|
41
|
+
let parsed;
|
|
42
|
+
try {
|
|
43
|
+
parsed = JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new Error(`${TOOL_CONTEXT_HEADER} must be valid JSON.`);
|
|
47
|
+
}
|
|
48
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
49
|
+
throw new Error(`${TOOL_CONTEXT_HEADER} must be a JSON object.`);
|
|
50
|
+
}
|
|
51
|
+
const source = parsed.source;
|
|
52
|
+
if (source === ToolInvocationSource.API) {
|
|
53
|
+
return { source: ToolInvocationSource.API };
|
|
54
|
+
}
|
|
55
|
+
if (source === ToolInvocationSource.THREAD) {
|
|
56
|
+
const threadId = parsed.threadId;
|
|
57
|
+
if (typeof threadId !== 'string' || !threadId) {
|
|
58
|
+
throw new Error(`${TOOL_CONTEXT_HEADER} thread invocation requires threadId.`);
|
|
59
|
+
}
|
|
60
|
+
return { source: ToolInvocationSource.THREAD, threadId };
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`${TOOL_CONTEXT_HEADER} source must be "thread" or "api".`);
|
|
63
|
+
}
|
|
64
|
+
export function isThreadToolInvocation(context) {
|
|
65
|
+
return context.source === ToolInvocationSource.THREAD;
|
|
66
|
+
}
|
|
19
67
|
/** Type-safe tools helper. Use: export const tools = defineTools([...]) */
|
|
20
68
|
export function defineTools(tools) {
|
|
21
69
|
return tools;
|
package/package.json
CHANGED
|
@@ -35,7 +35,7 @@ import type { Context } from 'hono';
|
|
|
35
35
|
import { cors } from 'hono/cors';
|
|
36
36
|
|
|
37
37
|
const apiKey = process.env.KAZZLE_API_KEY;
|
|
38
|
-
if (!apiKey) throw new Error('KAZZLE_API_KEY is required (mint with `api_key {
|
|
38
|
+
if (!apiKey) throw new Error('KAZZLE_API_KEY is required (mint with `api_key { create: {} }`)');
|
|
39
39
|
const apiUrl = process.env.KAZZLE_API_URL;
|
|
40
40
|
if (!apiUrl) throw new Error('KAZZLE_API_URL is required and must point at the matching Kazzle API environment');
|
|
41
41
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// Tool handlers receive Kazzle-Tool-Context — read with toolContext(req) from
|
|
2
|
+
// @kazzle/app/tools. Return { type: 'action_required', ... } only for thread
|
|
3
|
+
// calls; from the Tools API return a normal domain error. See documents/apps.md.
|
|
1
4
|
import { z } from 'zod';
|
|
2
5
|
import type { KazzleTool } from '@kazzle/app/tools';
|
|
3
6
|
|