@neta-art/cohub-cli 1.9.1 → 1.10.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.
@@ -1,5 +1,6 @@
1
1
  import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
2
2
  import { basename, dirname, extname, join } from "node:path";
3
+ import { GenerationPolicyError, assertGenerationRequestAllowedByPolicy, parseGenerationPolicyFromEnv, } from "@neta-art/cohub";
3
4
  import { createClient } from "../client.js";
4
5
  import { resolveSpace } from "../space.js";
5
6
  import { json as outJson, jsonRequested, ok, error, handleHttp, spinner } from "../output.js";
@@ -153,6 +154,45 @@ function parseTimeoutMs(value) {
153
154
  return error("Invalid timeout", "--timeout-ms must be a positive integer");
154
155
  return timeoutMs;
155
156
  }
157
+ function envValue(name) {
158
+ const value = process.env[name]?.trim();
159
+ return value || undefined;
160
+ }
161
+ function parseMetadata(value) {
162
+ if (!value)
163
+ return undefined;
164
+ let parsed;
165
+ try {
166
+ parsed = JSON.parse(value);
167
+ }
168
+ catch {
169
+ return error("Invalid metadata", "--metadata must be a JSON object");
170
+ }
171
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
172
+ return error("Invalid metadata", "--metadata must be a JSON object");
173
+ }
174
+ return parsed;
175
+ }
176
+ function mergeCohubMetadata(metadata) {
177
+ const sessionId = envValue("COHUB_SESSION_ID");
178
+ const turnId = envValue("COHUB_TURN_ID");
179
+ const toolCallId = envValue("COHUB_TOOL_CALL_ID");
180
+ if (!sessionId && !turnId && !toolCallId)
181
+ return metadata;
182
+ const existingCohub = metadata?.cohub;
183
+ const cohub = existingCohub && typeof existingCohub === "object" && !Array.isArray(existingCohub)
184
+ ? existingCohub
185
+ : {};
186
+ return {
187
+ ...(metadata ?? {}),
188
+ cohub: {
189
+ ...cohub,
190
+ ...(sessionId ? { sessionId } : {}),
191
+ ...(turnId ? { turnId } : {}),
192
+ ...(toolCallId ? { toolCallId } : {}),
193
+ },
194
+ };
195
+ }
156
196
  export function registerGenerations(program) {
157
197
  program
158
198
  .command("generate")
@@ -184,13 +224,29 @@ Examples:
184
224
  content.push(...await Promise.all(opts.image.map((value) => contentFromPathOrUrl("image", value))));
185
225
  content.push(...await Promise.all(opts.video.map((value) => contentFromPathOrUrl("video", value))));
186
226
  content.push(...await Promise.all(opts.audio.map((value) => contentFromPathOrUrl("audio", value))));
227
+ const parameters = parseParams(opts.param, opts.parameters);
228
+ try {
229
+ assertGenerationRequestAllowedByPolicy({
230
+ policy: parseGenerationPolicyFromEnv(process.env),
231
+ model: opts.model,
232
+ parameters,
233
+ });
234
+ }
235
+ catch (policyError) {
236
+ if (policyError instanceof GenerationPolicyError)
237
+ return error("Generation settings", policyError.message);
238
+ throw policyError;
239
+ }
240
+ const metadata = mergeCohubMetadata(parseMetadata(opts.metadata));
187
241
  const client = createClient();
188
242
  const created = await client.generations.create({
189
243
  spaceId,
244
+ sessionId: envValue("COHUB_SESSION_ID"),
245
+ turnId: envValue("COHUB_TURN_ID"),
190
246
  model: opts.model,
191
247
  content,
192
- parameters: parseParams(opts.param, opts.parameters),
193
- metadata: opts.metadata ? JSON.parse(opts.metadata) : undefined,
248
+ parameters,
249
+ metadata,
194
250
  });
195
251
  if (opts.async) {
196
252
  if (jsonRequested(opts))
@@ -1,3 +1,4 @@
1
+ import { filterGenerationDeclarationsByPolicy, parseGenerationPolicyFromEnv, } from "@neta-art/cohub";
1
2
  import { createClient } from "../client.js";
2
3
  import { table, json as outJson, jsonRequested, error, handleHttp } from "../output.js";
3
4
  function toMultimodalModelSummary(model) {
@@ -88,7 +89,8 @@ Examples:
88
89
  try {
89
90
  if (opts.modelType === "multimodal") {
90
91
  const response = await client.models.listMultimodal();
91
- const models = response.models.map(toMultimodalModelSummary);
92
+ const filtered = filterGenerationDeclarationsByPolicy(response.models, parseGenerationPolicyFromEnv(process.env));
93
+ const models = filtered.map(toMultimodalModelSummary);
92
94
  if (jsonRequested(opts))
93
95
  return outJson({ models });
94
96
  table(models, [
@@ -127,7 +129,8 @@ Examples:
127
129
  const client = createClient();
128
130
  try {
129
131
  const response = await client.models.listMultimodal();
130
- const model = response.models.find((item) => item.model === modelId);
132
+ const models = filterGenerationDeclarationsByPolicy(response.models, parseGenerationPolicyFromEnv(process.env));
133
+ const model = models.find((item) => item.model === modelId);
131
134
  if (!model) {
132
135
  return error("Model not found", `No multimodal model named ${modelId}`);
133
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub-cli",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -16,7 +16,7 @@
16
16
  "@neta-art/generation": "^0.1.2",
17
17
  "commander": "^13.1.0",
18
18
  "sharp": "^0.34.5",
19
- "@neta-art/cohub": "1.17.0"
19
+ "@neta-art/cohub": "1.18.0"
20
20
  },
21
21
  "publishConfig": {
22
22
  "access": "public"