@x12i/api-hub-runtime 0.1.0 → 0.1.1
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 +7 -0
- package/dist/index.js +26 -10
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
package/dist/index.d.ts
CHANGED
|
@@ -47,11 +47,16 @@ export declare class Runtime {
|
|
|
47
47
|
connection(slug: string): ConnectionInfo;
|
|
48
48
|
list(filter?: ListFilter): {
|
|
49
49
|
total: number;
|
|
50
|
+
unique: number;
|
|
50
51
|
items: ConnectedItem[];
|
|
51
52
|
};
|
|
52
53
|
/** Every service and hub the operator can connect, with the env variable names and what each unlocks. */
|
|
53
54
|
connections(): ConnectionEntry[];
|
|
55
|
+
/** A planned alias with no implementation of its own is answered by the canonical capability. */
|
|
56
|
+
private aliasTarget;
|
|
54
57
|
describe(slug: string): {
|
|
58
|
+
servedVia: string | null;
|
|
59
|
+
upstreams: import("@x12i/api-hub-core").CatalogUpstream[];
|
|
55
60
|
limits: import("@x12i/api-hub-core").CapabilityLimits | null;
|
|
56
61
|
inputSchema: import("@x12i/api-hub-core").JsonSchema | null;
|
|
57
62
|
outputSchema: import("@x12i/api-hub-core").JsonSchema | null;
|
|
@@ -69,6 +74,7 @@ export declare class Runtime {
|
|
|
69
74
|
missing: MissingItem[];
|
|
70
75
|
summary: string | null;
|
|
71
76
|
mode: "sync" | "job" | null;
|
|
77
|
+
failover: boolean;
|
|
72
78
|
slug: string;
|
|
73
79
|
exampleApi: string | null;
|
|
74
80
|
hubs: string[];
|
|
@@ -87,6 +93,7 @@ export declare class Runtime {
|
|
|
87
93
|
status: import("@x12i/api-hub-core").Status;
|
|
88
94
|
statusReason: string | null;
|
|
89
95
|
wave: import("@x12i/api-hub-core").Wave | null;
|
|
96
|
+
aliasOf: string | null;
|
|
90
97
|
} | undefined;
|
|
91
98
|
call(slug: string, input: unknown, options: CallOptions): Promise<CallOutcome>;
|
|
92
99
|
job(id: string, auth: AuthContext): Promise<JobRecord | undefined>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
|
-
import { CapabilityRegistry, createLogger, createStubContext, findRepoRoot, HubError, invokeCapability, SERVICES, serviceCredentials, serviceState, stubLlm, stubModels, stubSearch, toJsonSchema, } from '@x12i/api-hub-core';
|
|
3
|
+
import { CapabilityRegistry, createLogger, createStubContext, findRepoRoot, HubError, invokeCapability, SERVICES, serviceCredentials, serviceState, stubLlm, stubModels, stubSearch, toJsonSchema, upstreamsOf, } from '@x12i/api-hub-core';
|
|
4
4
|
export { createServicesFromEnv } from "./services.js";
|
|
5
5
|
export { PLATFORM_ENV } from "./env.js";
|
|
6
6
|
const NOT_PERMITTED = new Set(['blocked-terms', 'excluded']);
|
|
@@ -59,15 +59,19 @@ export class Runtime {
|
|
|
59
59
|
list(filter = {}) {
|
|
60
60
|
const { connected, ...rest } = filter;
|
|
61
61
|
if (connected === undefined) {
|
|
62
|
-
const { total, items } = this.registry.list(rest);
|
|
63
|
-
return { total, items: items.map((item) => ({ ...item, ...this.connection(item.slug) })) };
|
|
62
|
+
const { total, unique, items } = this.registry.list(rest);
|
|
63
|
+
return { total, unique, items: items.map((item) => ({ ...item, ...this.connection(item.slug) })) };
|
|
64
64
|
}
|
|
65
65
|
const all = this.registry
|
|
66
66
|
.list({ ...rest, limit: undefined, offset: undefined })
|
|
67
67
|
.items.map((item) => ({ ...item, ...this.connection(item.slug) }))
|
|
68
68
|
.filter((item) => item.connected === connected);
|
|
69
69
|
const offset = rest.offset ?? 0;
|
|
70
|
-
return {
|
|
70
|
+
return {
|
|
71
|
+
total: all.length,
|
|
72
|
+
unique: all.filter((item) => !item.aliasOf).length,
|
|
73
|
+
items: rest.limit === undefined ? all.slice(offset) : all.slice(offset, offset + rest.limit),
|
|
74
|
+
};
|
|
71
75
|
}
|
|
72
76
|
/** Every service and hub the operator can connect, with the env variable names and what each unlocks. */
|
|
73
77
|
connections() {
|
|
@@ -88,19 +92,29 @@ export class Runtime {
|
|
|
88
92
|
});
|
|
89
93
|
return [...services, ...(this.connectionProvider?.entries() ?? [])];
|
|
90
94
|
}
|
|
95
|
+
/** A planned alias with no implementation of its own is answered by the canonical capability. */
|
|
96
|
+
aliasTarget(slug) {
|
|
97
|
+
const entry = this.registry.entry(slug);
|
|
98
|
+
if (!entry?.aliasOf || entry.status !== 'planned' || this.registry.served(slug))
|
|
99
|
+
return null;
|
|
100
|
+
return this.registry.served(entry.aliasOf) ? entry.aliasOf : null;
|
|
101
|
+
}
|
|
91
102
|
describe(slug) {
|
|
92
103
|
const item = this.registry.item(slug);
|
|
93
104
|
const entry = this.registry.entry(slug);
|
|
94
105
|
if (!item || !entry)
|
|
95
106
|
return undefined;
|
|
96
|
-
const
|
|
107
|
+
const via = this.aliasTarget(slug);
|
|
108
|
+
const shown = this.registry.served(slug) ?? (via ? this.registry.served(via) : undefined);
|
|
97
109
|
return {
|
|
98
110
|
...item,
|
|
99
111
|
...this.connection(slug),
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
112
|
+
servedVia: via,
|
|
113
|
+
upstreams: upstreamsOf(shown),
|
|
114
|
+
limits: shown?.limits ?? null,
|
|
115
|
+
inputSchema: shown ? toJsonSchema(shown.input, 'input') : null,
|
|
116
|
+
outputSchema: shown ? toJsonSchema(shown.output, 'output') : null,
|
|
117
|
+
examples: shown?.examples ?? [],
|
|
104
118
|
listings: entry.listings.map((l) => ({
|
|
105
119
|
hub: l.hub,
|
|
106
120
|
api: l.api,
|
|
@@ -117,7 +131,8 @@ export class Runtime {
|
|
|
117
131
|
if (!entry) {
|
|
118
132
|
return { kind: 'error', error: new HubError('unsupported', `Unknown capability: ${slug}`, { slug }) };
|
|
119
133
|
}
|
|
120
|
-
const
|
|
134
|
+
const via = this.aliasTarget(slug);
|
|
135
|
+
const impl = this.registry.served(slug) ?? (via ? this.registry.served(via) : undefined);
|
|
121
136
|
if (!impl) {
|
|
122
137
|
const code = NOT_PERMITTED.has(entry.status) ? 'not_permitted' : 'unsupported';
|
|
123
138
|
return {
|
|
@@ -125,6 +140,7 @@ export class Runtime {
|
|
|
125
140
|
error: new HubError(code, `Capability ${slug} is listed but not served (status: ${entry.status})`, {
|
|
126
141
|
status: entry.status,
|
|
127
142
|
reason: entry.statusReason,
|
|
143
|
+
...(entry.aliasOf ? { aliasOf: entry.aliasOf } : {}),
|
|
128
144
|
}),
|
|
129
145
|
};
|
|
130
146
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport {\n CapabilityRegistry,\n createLogger,\n createStubContext,\n findRepoRoot,\n HubError,\n invokeCapability,\n SERVICES,\n serviceCredentials,\n serviceState,\n stubLlm,\n stubModels,\n stubSearch,\n toJsonSchema,\n type AnyCapability,\n type AuthContext,\n type CapabilityFilter,\n type CatalogItem,\n type ConnectionEntry,\n type ConnectionInfo,\n type ConnectionProvider,\n type Ctx,\n type JobRecord,\n type JobRunner,\n type Logger,\n type MissingItem,\n type ServiceId,\n} from '@x12i/api-hub-core';\n\nexport type { JobRunner } from '@x12i/api-hub-core';\nexport { createServicesFromEnv, type Services } from './services.ts';\nexport { PLATFORM_ENV, type EnvVar } from './env.ts';\n\nexport type ContextServices = Omit<Ctx, 'auth' | 'signal' | 'log'>;\n\nexport interface RuntimeOptions {\n registry: CapabilityRegistry;\n services?: Partial<ContextServices>;\n jobs?: JobRunner;\n log?: Logger;\n /** Environment used to work out which services are connected. Defaults to process.env. */\n env?: Record<string, string | undefined>;\n /** Connection state for capabilities served by proxy routes (packages/upstream). */\n connections?: ConnectionProvider | ((registry: CapabilityRegistry) => ConnectionProvider);\n}\n\nexport interface ListFilter extends CapabilityFilter {\n /** Only capabilities that are served and fully connected (true) or served but missing something (false). */\n connected?: boolean;\n}\n\nexport type ConnectedItem = CatalogItem & ConnectionInfo;\n\nexport type CallOutcome =\n | { kind: 'result'; output: unknown }\n | { kind: 'job'; job: JobRecord }\n | { kind: 'error'; error: HubError };\n\nexport interface CallOptions {\n auth: AuthContext;\n signal?: AbortSignal;\n}\n\nconst NOT_PERMITTED = new Set(['blocked-terms', 'excluded']);\n\n/** The one call path shared by REST and MCP. */\nexport class Runtime {\n readonly registry: CapabilityRegistry;\n readonly log: Logger;\n private readonly services: Partial<ContextServices>;\n private readonly jobs: JobRunner | undefined;\n private readonly env: Record<string, string | undefined>;\n private readonly connectionProvider: ConnectionProvider | undefined;\n\n constructor(options: RuntimeOptions) {\n this.registry = options.registry;\n this.services = options.services ?? {};\n this.jobs = options.jobs;\n this.log = options.log ?? createLogger();\n this.env = options.env ?? process.env;\n this.connectionProvider = typeof options.connections === 'function' ? options.connections(options.registry) : options.connections;\n }\n\n makeCtx(auth: AuthContext, signal: AbortSignal, impl?: AnyCapability): Ctx {\n const declared = new Set((impl?.requires ?? []).map((r) => r.service));\n const credentials = (service: ServiceId) => {\n if (!declared.has(service)) throw new HubError('internal', 'Capability asked for a service it does not declare', { service });\n return serviceCredentials(service, this.env);\n };\n return createStubContext({ credentials, ...this.services, auth, signal, log: this.log });\n }\n\n /** An injected client decides (a stub means not connected); without one, the env set decides. */\n serviceConnected(id: ServiceId): boolean {\n const clients: Partial<Record<ServiceId, [unknown, unknown]>> = {\n llm: [this.services.llm, stubLlm],\n models: [this.services.models, stubModels],\n search: [this.services.search, stubSearch],\n };\n const injected = clients[id];\n if (injected?.[0]) return injected[0] !== injected[1];\n return serviceState(id, this.env).connected;\n }\n\n connection(slug: string): ConnectionInfo {\n const impl = this.registry.served(slug);\n if (!impl) return { connected: null, missing: [] };\n const fromProvider = this.connectionProvider?.capability(slug);\n if (fromProvider) return fromProvider;\n const missing: MissingItem[] = [];\n for (const { service } of impl.requires ?? []) {\n if (this.serviceConnected(service)) continue;\n missing.push({ kind: 'service', service, env: serviceState(service, this.env).missingEnv });\n }\n return { connected: missing.length === 0, missing };\n }\n\n list(filter: ListFilter = {}): { total: number; items: ConnectedItem[] } {\n const { connected, ...rest } = filter;\n if (connected === undefined) {\n const { total, items } = this.registry.list(rest);\n return { total, items: items.map((item) => ({ ...item, ...this.connection(item.slug) })) };\n }\n const all = this.registry\n .list({ ...rest, limit: undefined, offset: undefined })\n .items.map((item) => ({ ...item, ...this.connection(item.slug) }))\n .filter((item) => item.connected === connected);\n const offset = rest.offset ?? 0;\n return { total: all.length, items: rest.limit === undefined ? all.slice(offset) : all.slice(offset, offset + rest.limit) };\n }\n\n /** Every service and hub the operator can connect, with the env variable names and what each unlocks. */\n connections(): ConnectionEntry[] {\n const served = this.registry.servedCapabilities();\n const services = (Object.keys(SERVICES) as ServiceId[]).map((id): ConnectionEntry => {\n const service = SERVICES[id];\n const state = serviceState(id, this.env);\n return {\n kind: 'service',\n id,\n title: service.title,\n connected: this.serviceConnected(id),\n env: (service.envSets as readonly (readonly string[])[]).map((set) => set.join(' + ')),\n missingEnv: this.serviceConnected(id) ? [] : state.missingEnv,\n unlocks: served.filter((cap) => cap.requires?.some((r) => r.service === id)).length,\n docs: `docs/ENV.md#${id}`,\n };\n });\n return [...services, ...(this.connectionProvider?.entries() ?? [])];\n }\n\n describe(slug: string) {\n const item = this.registry.item(slug);\n const entry = this.registry.entry(slug);\n if (!item || !entry) return undefined;\n const impl = this.registry.served(slug);\n return {\n ...item,\n ...this.connection(slug),\n limits: impl?.limits ?? null,\n inputSchema: impl ? toJsonSchema(impl.input, 'input') : null,\n outputSchema: impl ? toJsonSchema(impl.output, 'output') : null,\n examples: impl?.examples ?? [],\n listings: entry.listings.map((l) => ({\n hub: l.hub,\n api: l.api,\n hubCategory: l.hubCategory,\n sourcing: l.sourcing,\n effort: l.effort,\n price: l.price,\n url: l.url,\n })),\n };\n }\n\n async call(slug: string, input: unknown, options: CallOptions): Promise<CallOutcome> {\n const entry = this.registry.entry(slug);\n if (!entry) {\n return { kind: 'error', error: new HubError('unsupported', `Unknown capability: ${slug}`, { slug }) };\n }\n const impl = this.registry.served(slug);\n if (!impl) {\n const code = NOT_PERMITTED.has(entry.status) ? 'not_permitted' : 'unsupported';\n return {\n kind: 'error',\n error: new HubError(code, `Capability ${slug} is listed but not served (status: ${entry.status})`, {\n status: entry.status,\n reason: entry.statusReason,\n }),\n };\n }\n\n if (impl.mode === 'job') {\n if (!this.jobs) return { kind: 'error', error: new HubError('unsupported', 'Async jobs are not configured') };\n const parsed = impl.input.safeParse(input ?? {});\n if (!parsed.success) {\n return {\n kind: 'error',\n error: new HubError('invalid_input', 'Input does not match the schema', {\n issues: parsed.error.issues.map((i) => ({ path: i.path.map(String).join('.'), message: i.message })),\n }),\n };\n }\n const job = await this.jobs.submit(impl, input, options.auth, (signal) => this.makeCtx(options.auth, signal, impl));\n return { kind: 'job', job };\n }\n\n const signal = options.signal ?? new AbortController().signal;\n const result = await invokeCapability(impl, input, this.makeCtx(options.auth, signal, impl));\n return result.ok ? { kind: 'result', output: result.output } : { kind: 'error', error: result.error };\n }\n\n async job(id: string, auth: AuthContext): Promise<JobRecord | undefined> {\n return this.jobs?.get(id, auth);\n }\n}\n\n/**\n * Loads `<repo>/.env` (or ENV_FILE) into process.env with Node's built-in loader. Variables\n * already set in the environment win. Returns the file used, or undefined when there is none.\n */\nexport function loadDotEnv(root: string = findRepoRoot()): string | undefined {\n const file = process.env.ENV_FILE ? resolve(root, process.env.ENV_FILE) : join(root, '.env');\n if (!existsSync(file)) return undefined;\n process.loadEnvFile(file);\n return file;\n}\n\nexport interface CreateRuntimeOptions extends Omit<RuntimeOptions, 'registry'> {\n root?: string;\n}\n\nexport async function createRuntime(options: CreateRuntimeOptions = {}): Promise<Runtime> {\n const registry = await CapabilityRegistry.load(options.root);\n return new Runtime({ ...options, registry });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/runtime/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,kBAAkB,EAClB,YAAY,EACZ,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,WAAW,GAcZ,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,qBAAqB,EAAiB,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,YAAY,EAAe,MAAM,UAAU,CAAC;AAgCrD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;AAE7D,gDAAgD;AAChD,MAAM,OAAO,OAAO;IACT,QAAQ,CAAqB;IAC7B,GAAG,CAAS;IACJ,QAAQ,CAA2B;IACnC,IAAI,CAAwB;IAC5B,GAAG,CAAqC;IACxC,kBAAkB,CAAiC;IAEpE,YAAY,OAAuB;QACjC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,YAAY,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QACtC,IAAI,CAAC,kBAAkB,GAAG,OAAO,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IACpI,CAAC;IAED,OAAO,CAAC,IAAiB,EAAE,MAAmB,EAAE,IAAoB;QAClE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACvE,MAAM,WAAW,GAAG,CAAC,OAAkB,EAAE,EAAE;YACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,oDAAoD,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9H,OAAO,kBAAkB,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,CAAC,CAAC;QACF,OAAO,iBAAiB,CAAC,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,iGAAiG;IACjG,gBAAgB,CAAC,EAAa;QAC5B,MAAM,OAAO,GAAmD;YAC9D,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;YACjC,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;YAC1C,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;SAC3C,CAAC;QACF,MAAM,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC;YAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtD,OAAO,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;IAC9C,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QAC/D,IAAI,YAAY;YAAE,OAAO,YAAY,CAAC;QACtC,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;YAC9C,IAAI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC7C,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,CAAC,SAAqB,EAAE;QAC1B,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;QACtC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrG,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ;aACtB,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;aACtD,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aACjE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QAChC,OAAO;YACL,KAAK,EAAE,GAAG,CAAC,MAAM;YACjB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;SAC7F,CAAC;IACJ,CAAC;IAED,yGAAyG;IACzG,WAAW;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAmB,EAAE;YAClF,MAAM,OAAO,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC7B,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,EAAE;gBACF,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,SAAS,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,GAAG,EAAG,OAAO,CAAC,OAA0C,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtF,UAAU,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU;gBAC7D,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM;gBACnF,IAAI,EAAE,eAAe,EAAE,EAAE;aAC1B,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,iGAAiG;IACzF,WAAW,CAAC,IAAY;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7F,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC1F,OAAO;YACL,GAAG,IAAI;YACP,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACxB,SAAS,EAAE,GAAG;YACd,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC;YAC7B,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,IAAI;YAC7B,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI;YAC9D,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI;YACjE,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,EAAE;YAC/B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnC,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,GAAG,EAAE,CAAC,CAAC,GAAG;gBACV,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,GAAG,EAAE,CAAC,CAAC,GAAG;aACX,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,KAAc,EAAE,OAAoB;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC,aAAa,EAAE,uBAAuB,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACxG,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACzF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC;YAC/E,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,IAAI,QAAQ,CAAC,IAAI,EAAE,cAAc,IAAI,sCAAsC,KAAK,CAAC,MAAM,GAAG,EAAE;oBACjG,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,MAAM,EAAE,KAAK,CAAC,YAAY;oBAC1B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACrD,CAAC;aACH,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC,aAAa,EAAE,+BAA+B,CAAC,EAAE,CAAC;YAC9G,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,OAAO;oBACL,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,IAAI,QAAQ,CAAC,eAAe,EAAE,iCAAiC,EAAE;wBACtE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;qBACrG,CAAC;iBACH,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YACpH,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC,MAAM,CAAC;QAC9D,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACxG,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,IAAiB;QACrC,OAAO,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAe,YAAY,EAAE;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7F,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAgC,EAAE;IACpE,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,IAAI,OAAO,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport {\n CapabilityRegistry,\n createLogger,\n createStubContext,\n findRepoRoot,\n HubError,\n invokeCapability,\n SERVICES,\n serviceCredentials,\n serviceState,\n stubLlm,\n stubModels,\n stubSearch,\n toJsonSchema,\n upstreamsOf,\n type AnyCapability,\n type AuthContext,\n type CapabilityFilter,\n type CatalogItem,\n type ConnectionEntry,\n type ConnectionInfo,\n type ConnectionProvider,\n type Ctx,\n type JobRecord,\n type JobRunner,\n type Logger,\n type MissingItem,\n type ServiceId,\n} from '@x12i/api-hub-core';\n\nexport type { JobRunner } from '@x12i/api-hub-core';\nexport { createServicesFromEnv, type Services } from './services.ts';\nexport { PLATFORM_ENV, type EnvVar } from './env.ts';\n\nexport type ContextServices = Omit<Ctx, 'auth' | 'signal' | 'log'>;\n\nexport interface RuntimeOptions {\n registry: CapabilityRegistry;\n services?: Partial<ContextServices>;\n jobs?: JobRunner;\n log?: Logger;\n /** Environment used to work out which services are connected. Defaults to process.env. */\n env?: Record<string, string | undefined>;\n /** Connection state for capabilities served by proxy routes (packages/upstream). */\n connections?: ConnectionProvider | ((registry: CapabilityRegistry) => ConnectionProvider);\n}\n\nexport interface ListFilter extends CapabilityFilter {\n /** Only capabilities that are served and fully connected (true) or served but missing something (false). */\n connected?: boolean;\n}\n\nexport type ConnectedItem = CatalogItem & ConnectionInfo;\n\nexport type CallOutcome =\n | { kind: 'result'; output: unknown }\n | { kind: 'job'; job: JobRecord }\n | { kind: 'error'; error: HubError };\n\nexport interface CallOptions {\n auth: AuthContext;\n signal?: AbortSignal;\n}\n\nconst NOT_PERMITTED = new Set(['blocked-terms', 'excluded']);\n\n/** The one call path shared by REST and MCP. */\nexport class Runtime {\n readonly registry: CapabilityRegistry;\n readonly log: Logger;\n private readonly services: Partial<ContextServices>;\n private readonly jobs: JobRunner | undefined;\n private readonly env: Record<string, string | undefined>;\n private readonly connectionProvider: ConnectionProvider | undefined;\n\n constructor(options: RuntimeOptions) {\n this.registry = options.registry;\n this.services = options.services ?? {};\n this.jobs = options.jobs;\n this.log = options.log ?? createLogger();\n this.env = options.env ?? process.env;\n this.connectionProvider = typeof options.connections === 'function' ? options.connections(options.registry) : options.connections;\n }\n\n makeCtx(auth: AuthContext, signal: AbortSignal, impl?: AnyCapability): Ctx {\n const declared = new Set((impl?.requires ?? []).map((r) => r.service));\n const credentials = (service: ServiceId) => {\n if (!declared.has(service)) throw new HubError('internal', 'Capability asked for a service it does not declare', { service });\n return serviceCredentials(service, this.env);\n };\n return createStubContext({ credentials, ...this.services, auth, signal, log: this.log });\n }\n\n /** An injected client decides (a stub means not connected); without one, the env set decides. */\n serviceConnected(id: ServiceId): boolean {\n const clients: Partial<Record<ServiceId, [unknown, unknown]>> = {\n llm: [this.services.llm, stubLlm],\n models: [this.services.models, stubModels],\n search: [this.services.search, stubSearch],\n };\n const injected = clients[id];\n if (injected?.[0]) return injected[0] !== injected[1];\n return serviceState(id, this.env).connected;\n }\n\n connection(slug: string): ConnectionInfo {\n const impl = this.registry.served(slug);\n if (!impl) return { connected: null, missing: [] };\n const fromProvider = this.connectionProvider?.capability(slug);\n if (fromProvider) return fromProvider;\n const missing: MissingItem[] = [];\n for (const { service } of impl.requires ?? []) {\n if (this.serviceConnected(service)) continue;\n missing.push({ kind: 'service', service, env: serviceState(service, this.env).missingEnv });\n }\n return { connected: missing.length === 0, missing };\n }\n\n list(filter: ListFilter = {}): { total: number; unique: number; items: ConnectedItem[] } {\n const { connected, ...rest } = filter;\n if (connected === undefined) {\n const { total, unique, items } = this.registry.list(rest);\n return { total, unique, items: items.map((item) => ({ ...item, ...this.connection(item.slug) })) };\n }\n const all = this.registry\n .list({ ...rest, limit: undefined, offset: undefined })\n .items.map((item) => ({ ...item, ...this.connection(item.slug) }))\n .filter((item) => item.connected === connected);\n const offset = rest.offset ?? 0;\n return {\n total: all.length,\n unique: all.filter((item) => !item.aliasOf).length,\n items: rest.limit === undefined ? all.slice(offset) : all.slice(offset, offset + rest.limit),\n };\n }\n\n /** Every service and hub the operator can connect, with the env variable names and what each unlocks. */\n connections(): ConnectionEntry[] {\n const served = this.registry.servedCapabilities();\n const services = (Object.keys(SERVICES) as ServiceId[]).map((id): ConnectionEntry => {\n const service = SERVICES[id];\n const state = serviceState(id, this.env);\n return {\n kind: 'service',\n id,\n title: service.title,\n connected: this.serviceConnected(id),\n env: (service.envSets as readonly (readonly string[])[]).map((set) => set.join(' + ')),\n missingEnv: this.serviceConnected(id) ? [] : state.missingEnv,\n unlocks: served.filter((cap) => cap.requires?.some((r) => r.service === id)).length,\n docs: `docs/ENV.md#${id}`,\n };\n });\n return [...services, ...(this.connectionProvider?.entries() ?? [])];\n }\n\n /** A planned alias with no implementation of its own is answered by the canonical capability. */\n private aliasTarget(slug: string): string | null {\n const entry = this.registry.entry(slug);\n if (!entry?.aliasOf || entry.status !== 'planned' || this.registry.served(slug)) return null;\n return this.registry.served(entry.aliasOf) ? entry.aliasOf : null;\n }\n\n describe(slug: string) {\n const item = this.registry.item(slug);\n const entry = this.registry.entry(slug);\n if (!item || !entry) return undefined;\n const via = this.aliasTarget(slug);\n const shown = this.registry.served(slug) ?? (via ? this.registry.served(via) : undefined);\n return {\n ...item,\n ...this.connection(slug),\n servedVia: via,\n upstreams: upstreamsOf(shown),\n limits: shown?.limits ?? null,\n inputSchema: shown ? toJsonSchema(shown.input, 'input') : null,\n outputSchema: shown ? toJsonSchema(shown.output, 'output') : null,\n examples: shown?.examples ?? [],\n listings: entry.listings.map((l) => ({\n hub: l.hub,\n api: l.api,\n hubCategory: l.hubCategory,\n sourcing: l.sourcing,\n effort: l.effort,\n price: l.price,\n url: l.url,\n })),\n };\n }\n\n async call(slug: string, input: unknown, options: CallOptions): Promise<CallOutcome> {\n const entry = this.registry.entry(slug);\n if (!entry) {\n return { kind: 'error', error: new HubError('unsupported', `Unknown capability: ${slug}`, { slug }) };\n }\n const via = this.aliasTarget(slug);\n const impl = this.registry.served(slug) ?? (via ? this.registry.served(via) : undefined);\n if (!impl) {\n const code = NOT_PERMITTED.has(entry.status) ? 'not_permitted' : 'unsupported';\n return {\n kind: 'error',\n error: new HubError(code, `Capability ${slug} is listed but not served (status: ${entry.status})`, {\n status: entry.status,\n reason: entry.statusReason,\n ...(entry.aliasOf ? { aliasOf: entry.aliasOf } : {}),\n }),\n };\n }\n\n if (impl.mode === 'job') {\n if (!this.jobs) return { kind: 'error', error: new HubError('unsupported', 'Async jobs are not configured') };\n const parsed = impl.input.safeParse(input ?? {});\n if (!parsed.success) {\n return {\n kind: 'error',\n error: new HubError('invalid_input', 'Input does not match the schema', {\n issues: parsed.error.issues.map((i) => ({ path: i.path.map(String).join('.'), message: i.message })),\n }),\n };\n }\n const job = await this.jobs.submit(impl, input, options.auth, (signal) => this.makeCtx(options.auth, signal, impl));\n return { kind: 'job', job };\n }\n\n const signal = options.signal ?? new AbortController().signal;\n const result = await invokeCapability(impl, input, this.makeCtx(options.auth, signal, impl));\n return result.ok ? { kind: 'result', output: result.output } : { kind: 'error', error: result.error };\n }\n\n async job(id: string, auth: AuthContext): Promise<JobRecord | undefined> {\n return this.jobs?.get(id, auth);\n }\n}\n\n/**\n * Loads `<repo>/.env` (or ENV_FILE) into process.env with Node's built-in loader. Variables\n * already set in the environment win. Returns the file used, or undefined when there is none.\n */\nexport function loadDotEnv(root: string = findRepoRoot()): string | undefined {\n const file = process.env.ENV_FILE ? resolve(root, process.env.ENV_FILE) : join(root, '.env');\n if (!existsSync(file)) return undefined;\n process.loadEnvFile(file);\n return file;\n}\n\nexport interface CreateRuntimeOptions extends Omit<RuntimeOptions, 'registry'> {\n root?: string;\n}\n\nexport async function createRuntime(options: CreateRuntimeOptions = {}): Promise<Runtime> {\n const registry = await CapabilityRegistry.load(options.root);\n return new Runtime({ ...options, registry });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x12i/api-hub-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Shared REST and MCP call path for the x12i API hub",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@x12i/api-hub-cache": "0.1.
|
|
35
|
-
"@x12i/api-hub-core": "0.1.
|
|
36
|
-
"@x12i/api-hub-dns": "0.1.
|
|
37
|
-
"@x12i/api-hub-files": "0.1.
|
|
38
|
-
"@x12i/api-hub-jobs": "0.1.
|
|
39
|
-
"@x12i/api-hub-llm": "0.1.
|
|
40
|
-
"@x12i/api-hub-models": "0.1.
|
|
41
|
-
"@x12i/api-hub-safe-fetch": "0.1.
|
|
42
|
-
"@x12i/api-hub-search": "0.1.
|
|
43
|
-
"@x12i/api-hub-upstream": "0.1.
|
|
34
|
+
"@x12i/api-hub-cache": "0.1.1",
|
|
35
|
+
"@x12i/api-hub-core": "0.1.1",
|
|
36
|
+
"@x12i/api-hub-dns": "0.1.1",
|
|
37
|
+
"@x12i/api-hub-files": "0.1.1",
|
|
38
|
+
"@x12i/api-hub-jobs": "0.1.1",
|
|
39
|
+
"@x12i/api-hub-llm": "0.1.1",
|
|
40
|
+
"@x12i/api-hub-models": "0.1.1",
|
|
41
|
+
"@x12i/api-hub-safe-fetch": "0.1.1",
|
|
42
|
+
"@x12i/api-hub-search": "0.1.1",
|
|
43
|
+
"@x12i/api-hub-upstream": "0.1.1"
|
|
44
44
|
}
|
|
45
45
|
}
|