@inhuman.tools/harness-provider-sdk 0.0.0-stage → 0.2.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.
Files changed (63) hide show
  1. package/LICENSE.md +7 -0
  2. package/dist/auth.d.ts +11 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +2 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/blobs.d.ts +13 -0
  7. package/dist/blobs.d.ts.map +1 -0
  8. package/dist/blobs.js +16 -0
  9. package/dist/blobs.js.map +1 -0
  10. package/dist/capabilities.d.ts +105 -0
  11. package/dist/capabilities.d.ts.map +1 -0
  12. package/dist/capabilities.js +32 -0
  13. package/dist/capabilities.js.map +1 -0
  14. package/dist/descriptor.d.ts +20 -0
  15. package/dist/descriptor.d.ts.map +1 -0
  16. package/dist/descriptor.js +39 -0
  17. package/dist/descriptor.js.map +1 -0
  18. package/dist/driver.d.ts +5 -0
  19. package/dist/driver.d.ts.map +1 -0
  20. package/dist/driver.js +9 -0
  21. package/dist/driver.js.map +1 -0
  22. package/dist/identity.d.ts +10 -0
  23. package/dist/identity.d.ts.map +1 -0
  24. package/dist/identity.js +11 -0
  25. package/dist/identity.js.map +1 -0
  26. package/dist/index.d.ts +19 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +18 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/parse.d.ts +3 -0
  31. package/dist/parse.d.ts.map +1 -0
  32. package/dist/parse.js +9 -0
  33. package/dist/parse.js.map +1 -0
  34. package/dist/registration.d.ts +24 -0
  35. package/dist/registration.d.ts.map +1 -0
  36. package/dist/registration.js +70 -0
  37. package/dist/registration.js.map +1 -0
  38. package/dist/schemas/index.d.ts +2 -0
  39. package/dist/schemas/index.d.ts.map +1 -0
  40. package/dist/schemas/index.js +2 -0
  41. package/dist/schemas/index.js.map +1 -0
  42. package/dist/schemas/provider.d.ts +178 -0
  43. package/dist/schemas/provider.d.ts.map +1 -0
  44. package/dist/schemas/provider.js +100 -0
  45. package/dist/schemas/provider.js.map +1 -0
  46. package/dist/visuals.d.ts +12 -0
  47. package/dist/visuals.d.ts.map +1 -0
  48. package/dist/visuals.js +15 -0
  49. package/dist/visuals.js.map +1 -0
  50. package/package.json +49 -3
  51. package/src/auth.ts +11 -0
  52. package/src/blobs.ts +21 -0
  53. package/src/capabilities.ts +127 -0
  54. package/src/descriptor.ts +69 -0
  55. package/src/driver.ts +12 -0
  56. package/src/identity.ts +14 -0
  57. package/src/index.ts +33 -0
  58. package/src/parse.ts +9 -0
  59. package/src/registration.ts +108 -0
  60. package/src/schemas/index.ts +1 -0
  61. package/src/schemas/provider.ts +121 -0
  62. package/src/visuals.ts +20 -0
  63. package/README.md +0 -3
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @inhuman.tools/harness-provider-sdk — driver-provider descriptors,
3
+ * registration identity, and capability request/result contracts on PEW.
4
+ *
5
+ * Not a vendor completion class, not InhumanPlugin, not a plugin loader.
6
+ */
7
+
8
+ export type * from "./auth.js";
9
+ export { AUTH_INTERACTION_KINDS as AUTH_INTERACTION_KINDS } from "./schemas/index.js";
10
+ export * from "./blobs.js";
11
+ export * from "./capabilities.js";
12
+ export { CAPABILITY_KINDS as CAPABILITY_KINDS } from "./schemas/index.js";
13
+ export * from "./descriptor.js";
14
+ export * from "./driver.js";
15
+ export * from "./identity.js";
16
+ export { PROVIDER_SDK_CONTRACT as PROVIDER_SDK_CONTRACT } from "./schemas/index.js";
17
+ export * from "./registration.js";
18
+ export * from "./visuals.js";
19
+ export {
20
+ authInteractionSchema as authInteractionSchema,
21
+ capabilityKindSchema as capabilityKindSchema,
22
+ capabilityRequestSchema as capabilityRequestSchema,
23
+ completeRequestSchema as completeRequestSchema,
24
+ driverConnectionClassSchema as driverConnectionClassSchema,
25
+ driverDefinitionSchema as driverDefinitionSchema,
26
+ mcpCallRequestSchema as mcpCallRequestSchema,
27
+ multiplicitySchema as multiplicitySchema,
28
+ providerDescriptorSchema as providerDescriptorSchema,
29
+ providerRegistrationSchema as providerRegistrationSchema,
30
+ registeredDriverInputSchema as registeredDriverInputSchema,
31
+ webExtractRequestSchema as webExtractRequestSchema,
32
+ webSearchRequestSchema as webSearchRequestSchema,
33
+ } from "./schemas/index.js";
package/src/parse.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+
3
+ export function parseWith<T>(schema: z.ZodType<T>, value: unknown, context = "provider-sdk"): T {
4
+ const result = schema.safeParse(value);
5
+ if (result.success) return result.data;
6
+ const issue = result.error.issues[0];
7
+ const path = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
8
+ throw new Error(`${context}: ${path}${issue.message}`);
9
+ }
@@ -0,0 +1,108 @@
1
+ import type { DriverConnectionClass } from "@inhuman.tools/plexus-expectations/driver";
2
+
3
+ import type { CapabilityKind } from "./capabilities.js";
4
+ import { type DriverDefinition } from "./descriptor.js";
5
+ import { providerBrand, type ProviderSdkContract } from "./identity.js";
6
+ import { parseWith } from "./parse.js";
7
+ import { PROVIDER_SDK_CONTRACT } from "./schemas/index.js";
8
+ import { providerRegistrationSchema } from "./schemas/provider.js";
9
+
10
+ export type RegisteredDriver = DriverDefinition & {
11
+ readonly [providerBrand.driver]: true;
12
+ readonly providerId: string;
13
+ readonly connection: DriverConnectionClass;
14
+ };
15
+
16
+ export type RegisteredProvider = {
17
+ readonly [providerBrand.registration]: true;
18
+ readonly id: string;
19
+ readonly name: string;
20
+ readonly description: string;
21
+ readonly contract: ProviderSdkContract;
22
+ readonly drivers: readonly RegisteredDriver[];
23
+ };
24
+
25
+ function freezeRegisteredDriver(
26
+ providerId: string,
27
+ row: {
28
+ name: string;
29
+ description: string;
30
+ abilityClaim: readonly CapabilityKind[];
31
+ multiplicity: DriverDefinition["multiplicity"];
32
+ importPath?: string;
33
+ connection: DriverConnectionClass;
34
+ },
35
+ ): RegisteredDriver {
36
+ return Object.freeze({
37
+ [providerBrand.driver]: true as const,
38
+ providerId,
39
+ name: row.name,
40
+ description: row.description,
41
+ abilityClaim: Object.freeze([...row.abilityClaim]),
42
+ multiplicity: row.multiplicity,
43
+ importPath: row.importPath ?? row.name,
44
+ connection: row.connection,
45
+ });
46
+ }
47
+
48
+ function rejectDuplicateDrivers(drivers: readonly { name: string }[], context: string): void {
49
+ const seen = new Set<string>();
50
+ for (const driver of drivers) {
51
+ if (seen.has(driver.name)) throw new Error(`${context}: driver "${driver.name}" collides`);
52
+ seen.add(driver.name);
53
+ }
54
+ }
55
+
56
+ export function parseProviderRegistration(value: unknown): RegisteredProvider {
57
+ const parsed = parseWith(providerRegistrationSchema, value);
58
+ rejectDuplicateDrivers(parsed.drivers, "provider-sdk");
59
+ return Object.freeze({
60
+ [providerBrand.registration]: true as const,
61
+ id: parsed.id,
62
+ name: parsed.name,
63
+ description: parsed.description ?? "",
64
+ contract: PROVIDER_SDK_CONTRACT,
65
+ drivers: Object.freeze(parsed.drivers.map((row) => freezeRegisteredDriver(parsed.id, row))),
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Compose a roster. Duplicate provider ids or driver names fail before any
71
+ * connection is constructed — identity is catalog keys, not intern slots.
72
+ */
73
+ export function registerProviders(inputs: readonly unknown[]): RegisteredProvider[] {
74
+ const providers = inputs.map((input) => parseProviderRegistration(input));
75
+ const providerIds = new Set<string>();
76
+ const driverNames = new Set<string>();
77
+ for (const provider of providers) {
78
+ if (providerIds.has(provider.id)) {
79
+ throw new Error(`provider-sdk: provider "${provider.id}" collides`);
80
+ }
81
+ providerIds.add(provider.id);
82
+ for (const driver of provider.drivers) {
83
+ if (driverNames.has(driver.name)) {
84
+ throw new Error(`provider-sdk: driver "${driver.name}" collides`);
85
+ }
86
+ driverNames.add(driver.name);
87
+ }
88
+ }
89
+ return providers;
90
+ }
91
+
92
+ export function flattenDrivers(providers: readonly RegisteredProvider[]): readonly RegisteredDriver[] {
93
+ return providers.flatMap((provider) => provider.drivers);
94
+ }
95
+
96
+ export function isRegisteredProvider(value: unknown): value is RegisteredProvider {
97
+ return (
98
+ typeof value === "object" &&
99
+ value !== null &&
100
+ (value as { [k: symbol]: unknown })[providerBrand.registration] === true
101
+ );
102
+ }
103
+
104
+ export function isRegisteredDriver(value: unknown): value is RegisteredDriver {
105
+ return (
106
+ typeof value === "object" && value !== null && (value as { [k: symbol]: unknown })[providerBrand.driver] === true
107
+ );
108
+ }
@@ -0,0 +1 @@
1
+ export * from "./provider.js";
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Named Zod shapes for provider descriptors, driver rows, and capability
3
+ * request envelopes. Sole definition home for this package.
4
+ */
5
+ import { CompletionExpectation } from "@inhuman.tools/harness-model";
6
+ import { isDriverConnectionClass, type DriverConnectionClass } from "@inhuman.tools/plexus-expectations/driver";
7
+ import { z } from "zod";
8
+
9
+ export const PROVIDER_SDK_CONTRACT = 1 as const;
10
+
11
+ export const CAPABILITY_KINDS = ["completion", "mcp", "web-search", "web-extract"] as const;
12
+
13
+ export const capabilityKindSchema = z.enum(CAPABILITY_KINDS);
14
+
15
+ export const multiplicitySchema = z.enum(["add-by-default", "add-as-secondary"]);
16
+
17
+ const nonempty = z.string().trim().min(1, "non-empty string required");
18
+
19
+ const driverDefinitionObject = z.object({
20
+ name: nonempty,
21
+ description: nonempty,
22
+ abilityClaim: z.array(capabilityKindSchema).min(1, "driver abilityClaim must name at least one kind"),
23
+ multiplicity: multiplicitySchema,
24
+ importPath: nonempty.optional(),
25
+ });
26
+
27
+ function liftAbilityClaim(value: unknown): unknown {
28
+ if (value != null && typeof value === "object" && "can" in value && !("abilityClaim" in value)) {
29
+ const { can, ...rest } = value as { can: unknown };
30
+ return { ...rest, abilityClaim: can };
31
+ }
32
+ return value;
33
+ }
34
+
35
+ export const driverDefinitionSchema = z.preprocess(liftAbilityClaim, driverDefinitionObject);
36
+
37
+ export const providerDescriptorSchema = z.object({
38
+ id: nonempty,
39
+ name: nonempty,
40
+ description: z.string().optional(),
41
+ contract: z.literal(PROVIDER_SDK_CONTRACT, {
42
+ error: `contract is incompatible (supported: ${PROVIDER_SDK_CONTRACT})`,
43
+ }),
44
+ drivers: z.array(driverDefinitionSchema).min(1, "provider must declare at least one driver"),
45
+ });
46
+
47
+ export const driverConnectionClassSchema = z.custom<DriverConnectionClass>((value) => isDriverConnectionClass(value), {
48
+ message: "PEW driver connection class required",
49
+ });
50
+
51
+ export const registeredDriverInputSchema = driverDefinitionObject.extend({
52
+ connection: driverConnectionClassSchema,
53
+ });
54
+
55
+ export const providerRegistrationSchema = providerDescriptorSchema.extend({
56
+ drivers: z.array(registeredDriverInputSchema).min(1, "provider must declare at least one driver"),
57
+ });
58
+
59
+ const abortSignal = z.custom<AbortSignal>((value) => value instanceof AbortSignal, {
60
+ message: "AbortSignal required",
61
+ });
62
+
63
+ const completionRound = z.custom<CompletionExpectation>((value) => value instanceof CompletionExpectation, {
64
+ message: "completion round required",
65
+ });
66
+
67
+ export const completeRequestSchema = z.object({
68
+ connectionId: nonempty,
69
+ model: z.string(),
70
+ promptText: z.string().optional(),
71
+ messages: z.array(z.unknown()).optional(),
72
+ responseSchemaJson: z.string().optional(),
73
+ systemNote: z.string().optional(),
74
+ signal: abortSignal.optional(),
75
+ round: completionRound,
76
+ });
77
+
78
+ export const mcpCallRequestSchema = z.object({
79
+ connectionId: nonempty,
80
+ serverToolName: nonempty,
81
+ args: z.record(z.string(), z.unknown()).default({}),
82
+ signal: abortSignal.optional(),
83
+ onDispatch: z
84
+ .custom<() => void>((value) => typeof value === "function", {
85
+ message: "JS function required",
86
+ })
87
+ .optional(),
88
+ });
89
+
90
+ export const webSearchRequestSchema = z.object({
91
+ connectionId: nonempty,
92
+ query: nonempty,
93
+ limit: z.number().optional(),
94
+ signal: abortSignal.optional(),
95
+ });
96
+
97
+ export const webExtractRequestSchema = z.object({
98
+ connectionId: nonempty,
99
+ url: nonempty,
100
+ charLimit: z.number().optional(),
101
+ signal: abortSignal.optional(),
102
+ });
103
+
104
+ export const capabilityRequestSchema = z.discriminatedUnion("kind", [
105
+ z.object({ kind: z.literal("completion"), request: completeRequestSchema }),
106
+ z.object({ kind: z.literal("mcp"), request: mcpCallRequestSchema }),
107
+ z.object({ kind: z.literal("web-search"), request: webSearchRequestSchema }),
108
+ z.object({
109
+ kind: z.literal("web-extract"),
110
+ request: webExtractRequestSchema,
111
+ }),
112
+ ]);
113
+
114
+ export const AUTH_INTERACTION_KINDS = ["none", "login", "refresh", "logout"] as const;
115
+
116
+ export const authInteractionKindSchema = z.enum(AUTH_INTERACTION_KINDS);
117
+
118
+ export const authInteractionSchema = z.object({
119
+ kind: authInteractionKindSchema,
120
+ connectionId: nonempty,
121
+ });
package/src/visuals.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Read seam for stored pictures. The session's picture store belongs to the
3
+ * daemon; a provider that projects a turn onto its wire reads bytes through
4
+ * here and never imports the store.
5
+ */
6
+
7
+ /** Bytes of one stored picture, or null when the id is unknown or unreadable. */
8
+ export type VisualReader = (sessionId: string, id: string) => Uint8Array | null;
9
+
10
+ let reader: VisualReader | null = null;
11
+
12
+ /** The host that owns the store binds it once at boot. `null` unbinds. */
13
+ export function bindVisualReader(read: VisualReader | null): void {
14
+ reader = read;
15
+ }
16
+
17
+ /** Null while nothing is bound, so a wire projection names the picture as omitted. */
18
+ export function readVisual(sessionId: string, id: string): Uint8Array | null {
19
+ return reader === null ? null : reader(sessionId, id);
20
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.