@drawcall/market 0.1.74 → 0.1.76
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/agent.d.ts +2 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +15 -3
- package/dist/agent.js.map +1 -1
- package/dist/asset-implementation.d.ts +7 -0
- package/dist/asset-implementation.d.ts.map +1 -1
- package/dist/asset-implementation.js +1 -0
- package/dist/asset-implementation.js.map +1 -1
- package/dist/cli.js +8 -21
- package/dist/cli.js.map +1 -1
- package/dist/commands/agent.d.ts +2 -42
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +8 -382
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/generate.d.ts +2 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +3 -0
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/reference-images.d.ts +6 -0
- package/dist/commands/reference-images.d.ts.map +1 -0
- package/dist/commands/reference-images.js +28 -0
- package/dist/commands/reference-images.js.map +1 -0
- package/dist/contract.d.ts +4 -46
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +2 -8
- package/dist/contract.js.map +1 -1
- package/dist/generate.d.ts +2 -0
- package/dist/generate.d.ts.map +1 -1
- package/dist/generate.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +18 -48
- package/dist/output.js.map +1 -1
- package/dist/schemas.d.ts +3 -46
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +20 -46
- package/dist/schemas.js.map +1 -1
- package/dist/skill.d.ts +1 -1
- package/dist/skill.d.ts.map +1 -1
- package/dist/skill.js +2 -0
- package/dist/skill.js.map +1 -1
- package/package.json +1 -1
- package/skills/market/SKILL.md +2 -0
- package/src/agent.ts +17 -4
- package/src/asset-implementation.ts +8 -0
- package/src/cli.ts +19 -33
- package/src/commands/agent.ts +11 -474
- package/src/commands/generate.ts +5 -0
- package/src/commands/reference-images.ts +25 -0
- package/src/contract.ts +3 -9
- package/src/generate.ts +2 -0
- package/src/index.ts +0 -7
- package/src/output.ts +18 -56
- package/src/schemas.ts +24 -53
- package/src/skill.ts +2 -0
package/src/contract.ts
CHANGED
|
@@ -3,8 +3,6 @@ import { z } from 'zod'
|
|
|
3
3
|
import type { AssetFileManifest } from './schemas.js'
|
|
4
4
|
import {
|
|
5
5
|
MAX_UPLOAD_ZIP_SIZE_BYTES,
|
|
6
|
-
agentControlResultSchema,
|
|
7
|
-
agentDeferredStartSchema,
|
|
8
6
|
agentRunStatusSchema,
|
|
9
7
|
agentStartSchema,
|
|
10
8
|
agentStatusSchema,
|
|
@@ -104,6 +102,8 @@ export interface AssetInstallMetadata {
|
|
|
104
102
|
installMessage?: string
|
|
105
103
|
/** Omitted by Market APIs released before capability discovery. */
|
|
106
104
|
canGenerate?: boolean
|
|
105
|
+
/** Whether `generate` takes reference images for this type. */
|
|
106
|
+
acceptsReferenceImages?: boolean
|
|
107
107
|
saveOnInstall: boolean
|
|
108
108
|
readAssetDependenciesFromPackageJson: boolean
|
|
109
109
|
omitUnchangedInstalledFilesOnUpload: boolean
|
|
@@ -149,16 +149,10 @@ export const contract = {
|
|
|
149
149
|
// The agent plans, searches, judges and (where supported) generates a set of
|
|
150
150
|
// assets from a goal. `start` kicks off an async run; `status` long-polls it
|
|
151
151
|
// (blocks until the run settles or a heartbeat window elapses). The
|
|
152
|
-
// `agentAndWait` drives
|
|
153
|
-
// uses fail-closed `startDeferred`, observes `status`, then calls `approve`
|
|
154
|
-
// or `cancel`. Deferred semantics deliberately do not exist on `start`:
|
|
155
|
-
// an older worker could strip an unknown optional flag and spend immediately.
|
|
152
|
+
// `agentAndWait` client helper drives both.
|
|
156
153
|
agent: {
|
|
157
154
|
start: oc.input(agentStartSchema).output(z.object({ runId: z.string() })),
|
|
158
|
-
startDeferred: oc.input(agentDeferredStartSchema).output(z.object({ runId: z.string() })),
|
|
159
155
|
status: oc.input(agentStatusSchema).output(agentRunStatusSchema),
|
|
160
|
-
approve: oc.input(agentStatusSchema).output(agentControlResultSchema),
|
|
161
|
-
cancel: oc.input(agentStatusSchema).output(agentControlResultSchema),
|
|
162
156
|
},
|
|
163
157
|
},
|
|
164
158
|
|
package/src/generate.ts
CHANGED
|
@@ -11,6 +11,8 @@ export class GenerateError extends Error {
|
|
|
11
11
|
export interface GenerateInput {
|
|
12
12
|
description: string
|
|
13
13
|
type?: AssetType
|
|
14
|
+
/** Reference images (https URL or data URI) the result should match. */
|
|
15
|
+
referenceImages?: string[]
|
|
14
16
|
/** Requested visibility; omitted lets the server resolve it from entitlement. */
|
|
15
17
|
access?: AssetAccess
|
|
16
18
|
}
|
package/src/index.ts
CHANGED
|
@@ -67,11 +67,7 @@ export {
|
|
|
67
67
|
updateProfileSchema,
|
|
68
68
|
listAssetsSchema,
|
|
69
69
|
agentStartSchema,
|
|
70
|
-
agentDeferredStartSchema,
|
|
71
70
|
agentStatusSchema,
|
|
72
|
-
agentGenerationStateSchema,
|
|
73
|
-
agentControlStateSchema,
|
|
74
|
-
agentControlResultSchema,
|
|
75
71
|
agentResultAssetSchema,
|
|
76
72
|
agentResultSchema,
|
|
77
73
|
agentRunStatusSchema,
|
|
@@ -87,9 +83,6 @@ export type {
|
|
|
87
83
|
AgentResultAsset,
|
|
88
84
|
AgentResult,
|
|
89
85
|
AgentRunStatus,
|
|
90
|
-
AgentGenerationState,
|
|
91
|
-
AgentControlState,
|
|
92
|
-
AgentControlResult,
|
|
93
86
|
GenerateResponse,
|
|
94
87
|
GenerateJobStatus,
|
|
95
88
|
} from './schemas.js'
|
package/src/output.ts
CHANGED
|
@@ -103,7 +103,7 @@ export function assetTypesResult(metadata: Record<string, AssetInstallMetadata>)
|
|
|
103
103
|
|
|
104
104
|
const lines = ['Asset types:']
|
|
105
105
|
for (const [type, details] of types) {
|
|
106
|
-
lines.push(`- ${type} (${assetCapabilities(details
|
|
106
|
+
lines.push(`- ${type} (${assetCapabilities(details)})`)
|
|
107
107
|
if (details.searchMessage) {
|
|
108
108
|
lines.push(...block(' search: ', details.searchMessage))
|
|
109
109
|
}
|
|
@@ -111,10 +111,10 @@ export function assetTypesResult(metadata: Record<string, AssetInstallMetadata>)
|
|
|
111
111
|
return lines.join('\n')
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function assetCapabilities(
|
|
115
|
-
if (canGenerate ===
|
|
116
|
-
if (canGenerate
|
|
117
|
-
return 'search,
|
|
114
|
+
function assetCapabilities(details: AssetInstallMetadata): string {
|
|
115
|
+
if (details.canGenerate === undefined) return 'search, generation unknown'
|
|
116
|
+
if (!details.canGenerate) return 'search only'
|
|
117
|
+
return details.acceptsReferenceImages ? 'search, generate (reference images)' : 'search, generate'
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
function assetLine(asset: { name: string; version: string; type: string }): string {
|
|
@@ -122,12 +122,13 @@ function assetLine(asset: { name: string; version: string; type: string }): stri
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
function assetFileLines(paths: string[]): string[] {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
125
|
+
const files = unique(paths).sort((a, b) => a.localeCompare(b))
|
|
126
|
+
if (files.length === 0) return []
|
|
127
|
+
return [' files:', ...files.map((file) => ` ${installedFileLine(file)}`)]
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function installedFileLine(file: string): string {
|
|
131
|
+
return file.startsWith('public/') ? `${file} -> browser: /${file.slice('public/'.length)}` : file
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
function block(label: string, message: string, width = 68): string[] {
|
|
@@ -161,13 +162,17 @@ export function generatedInstallResult(
|
|
|
161
162
|
export function generationStartedResult(jobId: string): string {
|
|
162
163
|
return [
|
|
163
164
|
'Still generating after the normal wait — it continues in the background.',
|
|
164
|
-
`
|
|
165
|
+
`Resume this same job and install when ready: ${generationInstallCommand(jobId)}`,
|
|
165
166
|
].join('\n')
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
// Printed by `generate install` when the job is still running after its wait window.
|
|
169
170
|
export function generationRunningResult(jobId: string): string {
|
|
170
|
-
return `Still generating.
|
|
171
|
+
return `Still generating. Resume this same job: ${generationInstallCommand(jobId)}`
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function generationInstallCommand(jobId: string): string {
|
|
175
|
+
return `npx @drawcall/market@latest generate install ${jobId} --cwd "$PWD"`
|
|
171
176
|
}
|
|
172
177
|
|
|
173
178
|
export function uploadResult(name: string, version: string): string {
|
|
@@ -217,53 +222,10 @@ function normalizeInline(value: string): string {
|
|
|
217
222
|
return value.replace(/\s+/g, ' ').trim()
|
|
218
223
|
}
|
|
219
224
|
|
|
220
|
-
interface FileTreeNode {
|
|
221
|
-
children: Map<string, FileTreeNode>
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function fileTree(paths: string[]): string[] {
|
|
225
|
-
const root: FileTreeNode = { children: new Map() }
|
|
226
|
-
|
|
227
|
-
for (const filePath of paths) {
|
|
228
|
-
const parts = filePath.split('/').filter(Boolean)
|
|
229
|
-
let node = root
|
|
230
|
-
for (const part of parts) {
|
|
231
|
-
let child = node.children.get(part)
|
|
232
|
-
if (!child) {
|
|
233
|
-
child = { children: new Map() }
|
|
234
|
-
node.children.set(part, child)
|
|
235
|
-
}
|
|
236
|
-
node = child
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
return renderFileTree(root)
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
function renderFileTree(node: FileTreeNode, prefix = '', showConnector = false): string[] {
|
|
244
|
-
const entries = [...node.children.entries()].sort(([aName, aNode], [bName, bNode]) => {
|
|
245
|
-
const aIsDir = aNode.children.size > 0
|
|
246
|
-
const bIsDir = bNode.children.size > 0
|
|
247
|
-
if (aIsDir !== bIsDir) return aIsDir ? -1 : 1
|
|
248
|
-
return aName.localeCompare(bName)
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
return entries.flatMap(([name, child], index) => {
|
|
252
|
-
const isLast = index === entries.length - 1
|
|
253
|
-
const connector = showConnector ? (isLast ? '└─ ' : '├─ ') : ''
|
|
254
|
-
const childPrefix = showConnector ? prefix + (isLast ? ' ' : '│ ') : ''
|
|
255
|
-
return [`${prefix}${connector}${name}`, ...renderFileTree(child, childPrefix, true)]
|
|
256
|
-
})
|
|
257
|
-
}
|
|
258
|
-
|
|
259
225
|
function unique<T>(values: T[]): T[] {
|
|
260
226
|
return [...new Set(values)]
|
|
261
227
|
}
|
|
262
228
|
|
|
263
|
-
function indent(lines: string[], prefix: string): string[] {
|
|
264
|
-
return lines.map((line) => `${prefix}${line}`)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
229
|
function dependencyLines(label: string, deps: Record<string, string>): string[] {
|
|
268
230
|
const entries = Object.entries(deps)
|
|
269
231
|
if (entries.length === 0) return []
|
package/src/schemas.ts
CHANGED
|
@@ -106,9 +106,26 @@ export const fileManifestSchema = z.object({
|
|
|
106
106
|
*/
|
|
107
107
|
export type AssetFileManifest = Record<string, string>
|
|
108
108
|
|
|
109
|
+
// A phone-photo data URI is a few MB; this bounds worker and model payloads while staying far
|
|
110
|
+
// above what providers keep (images are downscaled upstream).
|
|
111
|
+
const MAX_REFERENCE_IMAGE_CHARS = 10_000_000
|
|
112
|
+
|
|
113
|
+
// Reference images the generated asset should match, each an http(s) URL or a
|
|
114
|
+
// `data:image/<type>;base64,<data>` URI. Only providers that declare
|
|
115
|
+
// `acceptsReferenceImages` take them, and none takes more than two.
|
|
116
|
+
export const referenceImagesSchema = z
|
|
117
|
+
.array(
|
|
118
|
+
z
|
|
119
|
+
.string()
|
|
120
|
+
.max(MAX_REFERENCE_IMAGE_CHARS)
|
|
121
|
+
.regex(/^(https?:\/\/|data:image\/)/, 'Must be an http(s) URL or a data:image URI'),
|
|
122
|
+
)
|
|
123
|
+
.max(2)
|
|
124
|
+
|
|
109
125
|
export const generateAssetSchema = z.object({
|
|
110
126
|
description: assetDescriptionSchema.min(3),
|
|
111
127
|
type: assetTypeSchema.optional(),
|
|
128
|
+
referenceImages: referenceImagesSchema.optional(),
|
|
112
129
|
// Requested visibility of the generated asset (same resolution as upload).
|
|
113
130
|
access: assetAccessSchema.optional(),
|
|
114
131
|
})
|
|
@@ -143,47 +160,16 @@ export type GenerateJobStatus = z.infer<typeof generateJobStatusSchema>
|
|
|
143
160
|
|
|
144
161
|
// The agent takes a natural-language goal (which carries the count and kinds,
|
|
145
162
|
// e.g. "3 low poly stones" or "a template for a zombie game, none if no fit")
|
|
146
|
-
// and optional reference images
|
|
163
|
+
// and optional reference images (http(s) URL or data URI).
|
|
147
164
|
export const agentStartSchema = z.strictObject({
|
|
148
165
|
goal: z.string().min(3).max(1000),
|
|
149
|
-
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
// A distinct procedure lets safety-critical callers fail closed against an
|
|
153
|
-
// older worker: an unknown `startDeferred` starts nothing. Deferred runs are
|
|
154
|
-
// goal-only because their restart input is persisted until the wall deadline;
|
|
155
|
-
// accepting unbounded base64 reference images would make that unsafe.
|
|
156
|
-
export const agentDeferredStartSchema = z.strictObject({
|
|
157
|
-
goal: agentStartSchema.shape.goal,
|
|
158
|
-
runId: z.string().uuid(),
|
|
166
|
+
referenceImages: referenceImagesSchema.optional(),
|
|
159
167
|
})
|
|
160
168
|
|
|
161
169
|
export const agentStatusSchema = z.object({
|
|
162
170
|
runId: z.string().min(1),
|
|
163
171
|
})
|
|
164
172
|
|
|
165
|
-
export const agentGenerationStateSchema = z.enum([
|
|
166
|
-
'deferred',
|
|
167
|
-
'awaiting-approval',
|
|
168
|
-
'approved',
|
|
169
|
-
'generation-started',
|
|
170
|
-
])
|
|
171
|
-
export type AgentGenerationState = z.infer<typeof agentGenerationStateSchema>
|
|
172
|
-
|
|
173
|
-
export const agentControlStateSchema = z.enum([
|
|
174
|
-
...agentGenerationStateSchema.options,
|
|
175
|
-
'completed',
|
|
176
|
-
'failed',
|
|
177
|
-
'cancelled',
|
|
178
|
-
])
|
|
179
|
-
export type AgentControlState = z.infer<typeof agentControlStateSchema>
|
|
180
|
-
|
|
181
|
-
export const agentControlResultSchema = z.object({
|
|
182
|
-
accepted: z.boolean(),
|
|
183
|
-
state: agentControlStateSchema,
|
|
184
|
-
})
|
|
185
|
-
export type AgentControlResult = z.infer<typeof agentControlResultSchema>
|
|
186
|
-
|
|
187
173
|
// One chosen asset: a verified, installable `name@version` (the agent only
|
|
188
174
|
// returns names the catalog resolved) plus a note on what it contributes.
|
|
189
175
|
export const agentResultAssetSchema = z.object({
|
|
@@ -203,27 +189,12 @@ export const agentResultSchema = z.object({
|
|
|
203
189
|
})
|
|
204
190
|
export type AgentResult = z.infer<typeof agentResultSchema>
|
|
205
191
|
|
|
206
|
-
// An agent run is an async job:
|
|
207
|
-
//
|
|
208
|
-
// keeps "completed without a result" and "failed without an error"
|
|
192
|
+
// An agent run is an async job: running, completed, or failed. A discriminated
|
|
193
|
+
// union keeps "completed without a result" and "failed without an error"
|
|
209
194
|
// unrepresentable.
|
|
210
195
|
export const agentRunStatusSchema = z.discriminatedUnion('status', [
|
|
211
|
-
z.object({
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
// worker during a rolling deploy.
|
|
215
|
-
generation: agentGenerationStateSchema.optional(),
|
|
216
|
-
}),
|
|
217
|
-
z.object({
|
|
218
|
-
status: z.literal('completed'),
|
|
219
|
-
result: agentResultSchema,
|
|
220
|
-
generationStarted: z.boolean().optional(),
|
|
221
|
-
}),
|
|
222
|
-
z.object({
|
|
223
|
-
status: z.literal('failed'),
|
|
224
|
-
error: z.string(),
|
|
225
|
-
generationStarted: z.boolean().optional(),
|
|
226
|
-
}),
|
|
227
|
-
z.object({ status: z.literal('cancelled'), generationStarted: z.boolean().optional() }),
|
|
196
|
+
z.object({ status: z.literal('running') }),
|
|
197
|
+
z.object({ status: z.literal('completed'), result: agentResultSchema }),
|
|
198
|
+
z.object({ status: z.literal('failed'), error: z.string() }),
|
|
228
199
|
])
|
|
229
200
|
export type AgentRunStatus = z.infer<typeof agentRunStatusSchema>
|
package/src/skill.ts
CHANGED
|
@@ -33,6 +33,8 @@ Install prints the exact files it wrote. It never searches or generates. With no
|
|
|
33
33
|
|
|
34
34
|
\`npx @drawcall/market generate --type <type> "<description>"\` creates and installs one provider-supported asset. It requires login and normally waits through provider generation before printing exact installed paths and type-specific usage guidance. Unsupported types report an error. If an unusually long job returns a continuation, run the printed \`generate install <jobId>\`; it resumes the same server-side job rather than generating again.
|
|
35
35
|
|
|
36
|
+
Add repeatable \`--reference-image <file-or-url>\` when the result should match given images; \`types\` shows which asset types accept reference images. A humanoid-model keeps the face and distinctive features of the person shown (at most 2 images). Types without reference image support reject them.
|
|
37
|
+
|
|
36
38
|
Add \`--access public\` or \`--access private\` when visibility matters. Omitted access follows the account entitlement; private generation requires \`market:private\`.
|
|
37
39
|
|
|
38
40
|
## Publish only when asked
|