@owlmeans/viable-common 0.0.11 → 0.0.13
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/README.md +68 -1
- package/agent-meta/manifest.json +23 -0
- package/agent-meta/skills/agent-presentation/SKILL.md +62 -0
- package/agent-meta/skills/viable-common/SKILL.md +180 -0
- package/build/agent/index.d.ts +1 -0
- package/build/agent/index.d.ts.map +1 -1
- package/build/agent/index.js +1 -0
- package/build/agent/index.js.map +1 -1
- package/build/agent/presentation.d.ts +102 -0
- package/build/agent/presentation.d.ts.map +1 -0
- package/build/agent/presentation.js +303 -0
- package/build/agent/presentation.js.map +1 -0
- package/build/blueprint/case.js +3 -3
- package/build/connect/consts.d.ts +93 -5
- package/build/connect/consts.d.ts.map +1 -1
- package/build/connect/consts.js +90 -1
- package/build/connect/consts.js.map +1 -1
- package/build/connect/entrypoints.d.ts +208 -4
- package/build/connect/entrypoints.d.ts.map +1 -1
- package/build/connect/entrypoints.js +61 -33
- package/build/connect/entrypoints.js.map +1 -1
- package/build/connect/errors.d.ts +20 -0
- package/build/connect/errors.d.ts.map +1 -1
- package/build/connect/errors.js +39 -0
- package/build/connect/errors.js.map +1 -1
- package/build/connect/ops.d.ts +46 -2
- package/build/connect/ops.d.ts.map +1 -1
- package/build/connect/references.d.ts +60 -1
- package/build/connect/references.d.ts.map +1 -1
- package/build/connect/references.js +16 -0
- package/build/connect/references.js.map +1 -1
- package/build/connect/schemas.d.ts +17 -2
- package/build/connect/schemas.d.ts.map +1 -1
- package/build/connect/schemas.js +91 -7
- package/build/connect/schemas.js.map +1 -1
- package/build/connect/types.d.ts +125 -1
- package/build/connect/types.d.ts.map +1 -1
- package/build/convert/consts.d.ts +539 -0
- package/build/convert/consts.d.ts.map +1 -0
- package/build/convert/consts.js +630 -0
- package/build/convert/consts.js.map +1 -0
- package/build/convert/helpers.d.ts +91 -0
- package/build/convert/helpers.d.ts.map +1 -0
- package/build/convert/helpers.js +301 -0
- package/build/convert/helpers.js.map +1 -0
- package/build/convert/index.d.ts +11 -0
- package/build/convert/index.d.ts.map +1 -0
- package/build/convert/index.js +4 -0
- package/build/convert/index.js.map +1 -0
- package/build/convert/schemas.d.ts +62 -0
- package/build/convert/schemas.d.ts.map +1 -0
- package/build/convert/schemas.js +626 -0
- package/build/convert/schemas.js.map +1 -0
- package/build/convert/types.d.ts +683 -0
- package/build/convert/types.d.ts.map +1 -0
- package/build/convert/types.js +2 -0
- package/build/convert/types.js.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/skills/catalogue.d.ts.map +1 -1
- package/build/skills/catalogue.js +76 -34
- package/build/skills/catalogue.js.map +1 -1
- package/build/slot/consts.d.ts +73 -2
- package/build/slot/consts.d.ts.map +1 -1
- package/build/slot/consts.js +105 -5
- package/build/slot/consts.js.map +1 -1
- package/build/slot/schemas.d.ts +9 -1
- package/build/slot/schemas.d.ts.map +1 -1
- package/build/slot/schemas.js +18 -0
- package/build/slot/schemas.js.map +1 -1
- package/build/slot/types.d.ts +71 -0
- package/build/slot/types.d.ts.map +1 -1
- package/package.json +15 -7
- package/src/agent/index.ts +1 -0
- package/src/agent/presentation.ts +335 -0
- package/src/blueprint/case.ts +3 -3
- package/src/connect/consts.ts +93 -1
- package/src/connect/entrypoints.ts +113 -40
- package/src/connect/errors.ts +44 -0
- package/src/connect/ops.ts +50 -2
- package/src/connect/references.ts +53 -5
- package/src/connect/schemas.ts +102 -13
- package/src/connect/types.ts +130 -2
- package/src/convert/consts.ts +672 -0
- package/src/convert/helpers.ts +340 -0
- package/src/convert/index.ts +10 -0
- package/src/convert/schemas.ts +663 -0
- package/src/convert/types.ts +741 -0
- package/src/index.ts +1 -0
- package/src/skills/catalogue.ts +76 -34
- package/src/slot/consts.ts +112 -6
- package/src/slot/schemas.ts +20 -1
- package/src/slot/types.ts +80 -0
- package/tests/connect-convert.spec.ts +162 -0
- package/tests/connect-entrypoints.spec.ts +12 -4
- package/tests/connect-errors.spec.ts +22 -0
- package/tests/convert.spec.ts +318 -0
- package/tests/presentation.spec.ts +85 -0
- package/tests/skills.spec.ts +47 -0
- /package/tests/{design.test.ts → design.spec.ts} +0 -0
package/src/connect/consts.ts
CHANGED
|
@@ -67,8 +67,20 @@ export enum ConnectExecutor {
|
|
|
67
67
|
Files = 'files',
|
|
68
68
|
Shell = 'shell',
|
|
69
69
|
Git = 'git',
|
|
70
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* The parent agent PERFORMS the model calls of a run: each one arrives as a `ModelTask`, is run
|
|
72
|
+
* in a clean subagent and submitted back. Present exactly when `llm` is `Local`.
|
|
73
|
+
*/
|
|
71
74
|
Model = 'model',
|
|
75
|
+
/**
|
|
76
|
+
* A PERSON can be asked a question and their answer brought back.
|
|
77
|
+
*
|
|
78
|
+
* Advertised always, and by every connector: a parent agent has a human in front of it by
|
|
79
|
+
* definition, which is the whole reason the platform can ask one anything at all. It is not a
|
|
80
|
+
* narrower `Model` — a model task is inference the platform pays for either way, an inquiry is
|
|
81
|
+
* a decision only a person can make, and a run that cannot ask assumes instead.
|
|
82
|
+
*/
|
|
83
|
+
Human = 'human',
|
|
72
84
|
}
|
|
73
85
|
|
|
74
86
|
/** What one operation asks a connector to do. */
|
|
@@ -79,6 +91,14 @@ export enum ConnectOpKind {
|
|
|
79
91
|
ModelTask = 'model-task',
|
|
80
92
|
/** Write the target's configuration (its `.env` files) and report what services are reachable. */
|
|
81
93
|
Configure = 'configure',
|
|
94
|
+
/**
|
|
95
|
+
* Put one question to the person the connector is working for, and bring back their answer.
|
|
96
|
+
*
|
|
97
|
+
* An operation like any other — queued to the project, redelivered to whichever session is
|
|
98
|
+
* attached, answered against its own op id — because the alternative was a second channel with
|
|
99
|
+
* its own delivery, expiry and reattachment rules for the one payload that already had them.
|
|
100
|
+
*/
|
|
101
|
+
Inquiry = 'inquiry',
|
|
82
102
|
}
|
|
83
103
|
|
|
84
104
|
/** How a connector is receiving operations. */
|
|
@@ -197,6 +217,18 @@ export enum ConnectJobKind {
|
|
|
197
217
|
StoryDevelop = 'story-develop',
|
|
198
218
|
FreeFlight = 'free-flight',
|
|
199
219
|
PipelineResume = 'pipeline-resume',
|
|
220
|
+
/**
|
|
221
|
+
* The four stages of a conversion, plus the purge.
|
|
222
|
+
*
|
|
223
|
+
* One kind per stage rather than one for the whole conversion: each stage is its own platform
|
|
224
|
+
* pipeline run, ends at a decision the user makes, and is looked up by the pipeline alias its
|
|
225
|
+
* kind names. A single `convert` kind would match whichever run row happened to be newest.
|
|
226
|
+
*/
|
|
227
|
+
ConvertIntake = 'convert-intake',
|
|
228
|
+
ConvertAnalysis = 'convert-analysis',
|
|
229
|
+
ConvertExtraction = 'convert-extraction',
|
|
230
|
+
ConvertImplementation = 'convert-implementation',
|
|
231
|
+
ConvertPurge = 'convert-purge',
|
|
200
232
|
}
|
|
201
233
|
|
|
202
234
|
export enum ConnectJobStatus {
|
|
@@ -216,8 +248,50 @@ export enum ConnectJobBlock {
|
|
|
216
248
|
LocalOp = 'local-op',
|
|
217
249
|
/** The local target has no database configured and the run needs one. */
|
|
218
250
|
Env = 'env',
|
|
251
|
+
/** A question is waiting for a person and nobody has answered it. */
|
|
252
|
+
Question = 'question',
|
|
219
253
|
}
|
|
220
254
|
|
|
255
|
+
/**
|
|
256
|
+
* The shapes a question can take on the wire.
|
|
257
|
+
*
|
|
258
|
+
* Mirrors `InquiryKind` in `@owlmeans/llm-common` value for value, and is deliberately a SEPARATE
|
|
259
|
+
* name rather than an import: the connect module is the wire contract and owns its own vocabulary
|
|
260
|
+
* — the same reason `ModelTask` mirrors `DelegatedTask` — which also keeps `manager-api`, which
|
|
261
|
+
* does not depend on the model runtime, free of `@owlmeans/llm-common`. Values are byte-identical,
|
|
262
|
+
* so the platform's mapper is a widening rather than a translation table, and a test pins that.
|
|
263
|
+
*/
|
|
264
|
+
export enum ConnectInquiryKind {
|
|
265
|
+
/** Pick one of the offered options, or several when `multiple` is set. */
|
|
266
|
+
Choice = 'choice',
|
|
267
|
+
/** Free text. */
|
|
268
|
+
Text = 'text',
|
|
269
|
+
/** Yes or no. */
|
|
270
|
+
Confirm = 'confirm',
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* How long the platform waits for a person to answer one question.
|
|
275
|
+
*
|
|
276
|
+
* The same forty-five minutes a model task gets, and for the same reason: the bound exists so a
|
|
277
|
+
* parent that has gone away eventually fails the step rather than holding a project lock forever,
|
|
278
|
+
* not to pace somebody who is thinking.
|
|
279
|
+
*/
|
|
280
|
+
export const CONNECT_INQUIRY_TIMEOUT_MS = 2_700_000
|
|
281
|
+
|
|
282
|
+
/** Options one choice question may offer. Beyond this it is a text question with a hint. */
|
|
283
|
+
export const CONNECT_INQUIRY_MAX_OPTIONS = 12
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* The ceiling on an answer's text.
|
|
287
|
+
*
|
|
288
|
+
* ONE ceiling for the whole stack: the twin is `DEFAULT_INQUIRY_ANSWER_CHARS` in
|
|
289
|
+
* `@owlmeans/llm-common`, and the two must stay equal. Two ceilings means the layer with the
|
|
290
|
+
* larger one truncates silently at the smaller, and the caller records an assumption about an
|
|
291
|
+
* answer the person actually gave.
|
|
292
|
+
*/
|
|
293
|
+
export const CONNECT_INQUIRY_MAX_TEXT = 2_000
|
|
294
|
+
|
|
221
295
|
/**
|
|
222
296
|
* How long a session survives without a sign of life.
|
|
223
297
|
*
|
|
@@ -295,6 +369,7 @@ export const CONNECT_EVENT_SESSION = 'connect:session'
|
|
|
295
369
|
export const CONNECT_OP_PUBSUB = 'connect-op-pubsub'
|
|
296
370
|
export const CONNECT_RESULT_PUBSUB = 'connect-result-pubsub'
|
|
297
371
|
export const CONNECT_OP_STORE = 'connect-op-store'
|
|
372
|
+
export const CONNECT_RESULT_STORE = 'connect-result-store'
|
|
298
373
|
export const CONNECT_SESSION_PUBSUB = 'connect-session-pubsub'
|
|
299
374
|
|
|
300
375
|
/** The backend resource alias for session records. */
|
|
@@ -333,8 +408,22 @@ export const connect = Object.freeze({
|
|
|
333
408
|
modify: 'viable:manager-api:connect:project:modify',
|
|
334
409
|
settings: 'viable:manager-api:connect:project:settings',
|
|
335
410
|
llm: 'viable:manager-api:connect:project:llm',
|
|
411
|
+
/** The per-project converter inference mode. Separate from `llm`: it is not a paid capability. */
|
|
412
|
+
converterLlm: 'viable:manager-api:connect:project:converter-llm',
|
|
336
413
|
job: 'viable:manager-api:connect:project:job',
|
|
337
414
|
}),
|
|
415
|
+
convert: Object.freeze({
|
|
416
|
+
create: 'viable:manager-api:connect:convert:create',
|
|
417
|
+
check: 'viable:manager-api:connect:convert:check',
|
|
418
|
+
start: 'viable:manager-api:connect:convert:start',
|
|
419
|
+
proceed: 'viable:manager-api:connect:convert:proceed',
|
|
420
|
+
cancel: 'viable:manager-api:connect:convert:cancel',
|
|
421
|
+
status: 'viable:manager-api:connect:convert:status',
|
|
422
|
+
purge: 'viable:manager-api:connect:convert:purge',
|
|
423
|
+
}),
|
|
424
|
+
inquiry: Object.freeze({
|
|
425
|
+
answer: 'viable:manager-api:connect:inquiry:answer',
|
|
426
|
+
}),
|
|
338
427
|
story: Object.freeze({
|
|
339
428
|
list: 'viable:manager-api:connect:story:list',
|
|
340
429
|
get: 'viable:manager-api:connect:story:get',
|
|
@@ -343,6 +432,9 @@ export const connect = Object.freeze({
|
|
|
343
432
|
delete: 'viable:manager-api:connect:story:delete',
|
|
344
433
|
develop: 'viable:manager-api:connect:story:develop',
|
|
345
434
|
}),
|
|
435
|
+
files: Object.freeze({
|
|
436
|
+
list: 'viable:manager-api:connect:files:list',
|
|
437
|
+
}),
|
|
346
438
|
pipeline: Object.freeze({
|
|
347
439
|
state: 'viable:manager-api:connect:pipeline:state',
|
|
348
440
|
resume: 'viable:manager-api:connect:pipeline:resume',
|
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { contract, openProtocol, protocol, typed } from '@owlmeans/entrypoint'
|
|
2
|
-
import type {
|
|
2
|
+
import type { EntrypointProtocol, OpenRequest, OpenValue } from '@owlmeans/entrypoint'
|
|
3
3
|
import { route, RouteMethod, socket } from '@owlmeans/route'
|
|
4
|
+
import { ConverterProjectLlmBodySchema } from '../convert/schemas.js'
|
|
4
5
|
import { connect } from './consts.js'
|
|
5
6
|
import {
|
|
6
|
-
ConnectAttachBodySchema, ConnectConfirmBodySchema,
|
|
7
|
+
ConnectAttachBodySchema, ConnectConfirmBodySchema, ConnectConvertCreateBodySchema,
|
|
8
|
+
ConnectConvertProceedBodySchema, ConnectCreateBodySchema, ConnectInquiryParamsSchema,
|
|
7
9
|
ConnectJobParamsSchema, ConnectModifyBodySchema, ConnectOpParamsSchema, ConnectOpResultSchema,
|
|
8
10
|
ConnectPipelineParamsSchema, ConnectPipelineResumeBodySchema, ConnectProjectIdSchema,
|
|
9
11
|
ConnectProjectLlmBodySchema, ConnectSessionOpenSchema, ConnectSessionParamsSchema,
|
|
10
|
-
ConnectStoryBodySchema, ConnectStoryParamsSchema, ConnectStoryQuerySchema, ConnectWaitQuerySchema
|
|
12
|
+
ConnectStoryBodySchema, ConnectStoryParamsSchema, ConnectStoryQuerySchema, ConnectWaitQuerySchema,
|
|
13
|
+
InquiryAnswerSchema,
|
|
11
14
|
} from './schemas.js'
|
|
12
15
|
import type {
|
|
13
|
-
ConnectAttachBody, ConnectConfirmBody,
|
|
16
|
+
ConnectAttachBody, ConnectConfirmBody, ConnectConvertCreateBody, ConnectConvertProceedBody,
|
|
17
|
+
ConnectCreateBody, ConnectInquiryAnswerBody, ConnectJob, ConnectJobParams, ConnectModifyBody,
|
|
14
18
|
ConnectPipelineParams, ConnectPipelineResumeBody, ConnectProjectLlmBody, ConnectSessionOpen,
|
|
15
|
-
ConnectSessionParams, ConnectStoryBody, ConnectStoryQuery, ConnectWaitQuery,
|
|
19
|
+
ConnectSessionParams, ConnectStoryBody, ConnectStoryQuery, ConnectWaitQuery, ConversionStatusView,
|
|
20
|
+
ConvertCheck,
|
|
16
21
|
} from './types.js'
|
|
17
22
|
import type { ConnectOpResult } from './ops.js'
|
|
23
|
+
import type { ConverterProjectLlmBody } from '../convert/types.js'
|
|
18
24
|
|
|
19
25
|
/**
|
|
20
26
|
* What the platform injects when it mounts the connector routes.
|
|
@@ -36,8 +42,8 @@ export interface ConnectEntrypointOptions {
|
|
|
36
42
|
* back by itself when a plan lapses.
|
|
37
43
|
*/
|
|
38
44
|
localLlm?: { alias: string, params: string[] }
|
|
39
|
-
/** The
|
|
40
|
-
updateBase:
|
|
45
|
+
/** The platform-owned websocket-base protocol that carries session updates. */
|
|
46
|
+
updateBase: EntrypointProtocol<OpenRequest, OpenValue>
|
|
41
47
|
/** Path prefix; defaults to `/connect`. */
|
|
42
48
|
path?: string
|
|
43
49
|
}
|
|
@@ -49,7 +55,7 @@ export interface ConnectEntrypointOptions {
|
|
|
49
55
|
* server-side and onto client entrypoints in the SDK — the same declarations both times, which is
|
|
50
56
|
* what makes a path or a schema impossible to get wrong on one side only.
|
|
51
57
|
*/
|
|
52
|
-
export const connectProtocols = (opts: ConnectEntrypointOptions)
|
|
58
|
+
export const connectProtocols = (opts: ConnectEntrypointOptions) => {
|
|
53
59
|
const prefix = opts.path ?? '/connect'
|
|
54
60
|
const ownership = opts.gate != null
|
|
55
61
|
? { guards: opts.guard, gate: opts.gate }
|
|
@@ -58,45 +64,48 @@ export const connectProtocols = (opts: ConnectEntrypointOptions): EntrypointTree
|
|
|
58
64
|
? { gate: opts.localLlm }
|
|
59
65
|
: undefined
|
|
60
66
|
|
|
67
|
+
const base = openProtocol(route(connect.base, prefix), ownership)
|
|
68
|
+
|
|
61
69
|
return {
|
|
62
|
-
base
|
|
70
|
+
base,
|
|
63
71
|
|
|
64
|
-
capabilities:
|
|
65
|
-
parent:
|
|
66
|
-
|
|
72
|
+
capabilities: protocol(
|
|
73
|
+
route(connect.capabilities, '/capabilities', { parent: base, method: RouteMethod.GET }),
|
|
74
|
+
contract(typed()),
|
|
75
|
+
),
|
|
67
76
|
|
|
68
77
|
// --- session ---------------------------------------------------------------------------
|
|
69
78
|
session: {
|
|
70
79
|
open: protocol(
|
|
71
|
-
route(connect.session.open, '/session', { parent:
|
|
80
|
+
route(connect.session.open, '/session', { parent: base, method: RouteMethod.POST }),
|
|
72
81
|
contract.request({ body: typed<ConnectSessionOpen>(ConnectSessionOpenSchema) }, typed())
|
|
73
82
|
),
|
|
74
83
|
openDelegated: protocol(
|
|
75
84
|
route(connect.session.openDelegated, '/session/delegated', {
|
|
76
|
-
parent:
|
|
85
|
+
parent: base, method: RouteMethod.POST
|
|
77
86
|
}),
|
|
78
87
|
contract.request({ body: typed<ConnectSessionOpen>(ConnectSessionOpenSchema) }, typed()), paid
|
|
79
88
|
),
|
|
80
89
|
get: protocol(
|
|
81
90
|
route(connect.session.get, '/session/:sessionId', {
|
|
82
|
-
parent:
|
|
91
|
+
parent: base, method: RouteMethod.GET
|
|
83
92
|
}),
|
|
84
93
|
contract.request({ params: typed<ConnectSessionParams>(ConnectSessionParamsSchema) }, typed())
|
|
85
94
|
),
|
|
86
95
|
heartbeat: protocol(
|
|
87
96
|
route(connect.session.heartbeat, '/session/:sessionId/heartbeat', {
|
|
88
|
-
parent:
|
|
97
|
+
parent: base, method: RouteMethod.POST
|
|
89
98
|
}),
|
|
90
99
|
contract.request({ params: typed<ConnectSessionParams>(ConnectSessionParamsSchema) }, typed())
|
|
91
100
|
),
|
|
92
101
|
close: protocol(
|
|
93
102
|
route(connect.session.close, '/session/:sessionId/close', {
|
|
94
|
-
parent:
|
|
103
|
+
parent: base, method: RouteMethod.POST
|
|
95
104
|
}),
|
|
96
105
|
contract.request({ params: typed<ConnectSessionParams>(ConnectSessionParamsSchema) }, typed())
|
|
97
106
|
),
|
|
98
107
|
socket: protocol(
|
|
99
|
-
route(connect.session.socket, '/connect/:sessionId', socket(opts.updateBase)),
|
|
108
|
+
route(connect.session.socket, '/connect/:sessionId', socket({ parent: opts.updateBase })),
|
|
100
109
|
contract.request({ params: typed<ConnectSessionParams>(ConnectSessionParamsSchema) }, typed())
|
|
101
110
|
),
|
|
102
111
|
|
|
@@ -106,13 +115,13 @@ export const connectProtocols = (opts: ConnectEntrypointOptions): EntrypointTree
|
|
|
106
115
|
op: {
|
|
107
116
|
pull: protocol(
|
|
108
117
|
route(connect.op.pull, '/session/:sessionId/ops', {
|
|
109
|
-
parent:
|
|
118
|
+
parent: base, method: RouteMethod.GET
|
|
110
119
|
}),
|
|
111
120
|
contract.request({ params: typed<ConnectSessionParams>(ConnectSessionParamsSchema), query: typed<ConnectWaitQuery>(ConnectWaitQuerySchema) }, typed())
|
|
112
121
|
),
|
|
113
122
|
submit: protocol(
|
|
114
123
|
route(connect.op.submit, '/session/:sessionId/ops/:opId', {
|
|
115
|
-
parent:
|
|
124
|
+
parent: base, method: RouteMethod.POST
|
|
116
125
|
}),
|
|
117
126
|
contract.request({ params: typed<{ sessionId: string, opId: string }>(ConnectOpParamsSchema), body: typed<ConnectOpResult>(ConnectOpResultSchema) }, typed())
|
|
118
127
|
),
|
|
@@ -122,57 +131,67 @@ export const connectProtocols = (opts: ConnectEntrypointOptions): EntrypointTree
|
|
|
122
131
|
// --- project ---------------------------------------------------------------------------
|
|
123
132
|
project: {
|
|
124
133
|
create: protocol(
|
|
125
|
-
route(connect.project.create, '/project', { parent:
|
|
134
|
+
route(connect.project.create, '/project', { parent: base, method: RouteMethod.POST }),
|
|
126
135
|
contract.request({ body: typed<ConnectCreateBody>(ConnectCreateBodySchema) }, typed())
|
|
127
136
|
),
|
|
128
|
-
list:
|
|
129
|
-
parent:
|
|
130
|
-
|
|
137
|
+
list: protocol(
|
|
138
|
+
route(connect.project.list, '/project', { parent: base, method: RouteMethod.GET }),
|
|
139
|
+
contract(typed()),
|
|
140
|
+
),
|
|
131
141
|
attach: protocol(
|
|
132
142
|
route(connect.project.attach, '/project/attach', {
|
|
133
|
-
parent:
|
|
143
|
+
parent: base, method: RouteMethod.POST
|
|
134
144
|
}),
|
|
135
145
|
contract.request({ body: typed<ConnectAttachBody>(ConnectAttachBodySchema) }, typed())
|
|
136
146
|
),
|
|
137
147
|
confirm: protocol(
|
|
138
148
|
route(connect.project.confirm, '/project/:id/confirm', {
|
|
139
|
-
parent:
|
|
149
|
+
parent: base, method: RouteMethod.POST
|
|
140
150
|
}),
|
|
141
151
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema), body: typed<ConnectConfirmBody>(ConnectConfirmBodySchema) }, typed())
|
|
142
152
|
),
|
|
143
153
|
status: protocol(
|
|
144
154
|
route(connect.project.status, '/project/:id/status', {
|
|
145
|
-
parent:
|
|
155
|
+
parent: base, method: RouteMethod.GET
|
|
146
156
|
}),
|
|
147
157
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed())
|
|
148
158
|
),
|
|
149
159
|
reinit: protocol(
|
|
150
160
|
route(connect.project.reinit, '/project/:id/reinit', {
|
|
151
|
-
parent:
|
|
161
|
+
parent: base, method: RouteMethod.POST
|
|
152
162
|
}),
|
|
153
163
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed())
|
|
154
164
|
),
|
|
155
165
|
modify: protocol(
|
|
156
166
|
route(connect.project.modify, '/project/:id/modify', {
|
|
157
|
-
parent:
|
|
167
|
+
parent: base, method: RouteMethod.POST
|
|
158
168
|
}),
|
|
159
169
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema), body: typed<ConnectModifyBody>(ConnectModifyBodySchema) }, typed())
|
|
160
170
|
),
|
|
161
171
|
settings: protocol(
|
|
162
172
|
route(connect.project.settings, '/project/:id/settings', {
|
|
163
|
-
parent:
|
|
173
|
+
parent: base, method: RouteMethod.GET
|
|
164
174
|
}),
|
|
165
175
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed())
|
|
166
176
|
),
|
|
167
177
|
llm: protocol(
|
|
168
178
|
route(connect.project.llm, '/project/:id/llm', {
|
|
169
|
-
parent:
|
|
179
|
+
parent: base, method: RouteMethod.POST
|
|
170
180
|
}),
|
|
171
181
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema), body: typed<ConnectProjectLlmBody>(ConnectProjectLlmBodySchema) }, typed()), paid
|
|
172
182
|
),
|
|
183
|
+
converterLlm: protocol(
|
|
184
|
+
route(connect.project.converterLlm, '/project/:id/converter-llm', {
|
|
185
|
+
parent: base, method: RouteMethod.POST,
|
|
186
|
+
}),
|
|
187
|
+
contract.request({
|
|
188
|
+
params: typed<{ id: string }>(ConnectProjectIdSchema),
|
|
189
|
+
body: typed<ConverterProjectLlmBody>(ConverterProjectLlmBodySchema),
|
|
190
|
+
}, typed()),
|
|
191
|
+
),
|
|
173
192
|
job: protocol(
|
|
174
193
|
route(connect.project.job, '/project/:id/job/:jobId', {
|
|
175
|
-
parent:
|
|
194
|
+
parent: base, method: RouteMethod.GET
|
|
176
195
|
}),
|
|
177
196
|
contract.request({ params: typed<ConnectJobParams>(ConnectJobParamsSchema), query: typed<ConnectWaitQuery>(ConnectWaitQuerySchema) }, typed())
|
|
178
197
|
),
|
|
@@ -182,51 +201,105 @@ export const connectProtocols = (opts: ConnectEntrypointOptions): EntrypointTree
|
|
|
182
201
|
// --- stories ---------------------------------------------------------------------------
|
|
183
202
|
story: {
|
|
184
203
|
list: protocol(
|
|
185
|
-
route(connect.story.list, '/story/:id', { parent:
|
|
204
|
+
route(connect.story.list, '/story/:id', { parent: base, method: RouteMethod.GET }),
|
|
186
205
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema), query: typed<ConnectStoryQuery>(ConnectStoryQuerySchema) }, typed())
|
|
187
206
|
),
|
|
188
207
|
create: protocol(
|
|
189
|
-
route(connect.story.create, '/story/:id', { parent:
|
|
208
|
+
route(connect.story.create, '/story/:id', { parent: base, method: RouteMethod.POST }),
|
|
190
209
|
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema), body: typed<ConnectStoryBody>(ConnectStoryBodySchema) }, typed())
|
|
191
210
|
),
|
|
192
211
|
get: protocol(
|
|
193
212
|
route(connect.story.get, '/story/:id/:storyId', {
|
|
194
|
-
parent:
|
|
213
|
+
parent: base, method: RouteMethod.GET
|
|
195
214
|
}),
|
|
196
215
|
contract.request({ params: typed<{ id: string, storyId: string }>(ConnectStoryParamsSchema) }, typed())
|
|
197
216
|
),
|
|
198
217
|
update: protocol(
|
|
199
218
|
route(connect.story.update, '/story/:id/:storyId', {
|
|
200
|
-
parent:
|
|
219
|
+
parent: base, method: RouteMethod.PUT
|
|
201
220
|
}),
|
|
202
221
|
contract.request({ params: typed<{ id: string, storyId: string }>(ConnectStoryParamsSchema), body: typed<ConnectStoryBody>(ConnectStoryBodySchema) }, typed())
|
|
203
222
|
),
|
|
204
223
|
delete: protocol(
|
|
205
224
|
route(connect.story.delete, '/story/:id/:storyId', {
|
|
206
|
-
parent:
|
|
225
|
+
parent: base, method: RouteMethod.DELETE
|
|
207
226
|
}),
|
|
208
227
|
contract.request({ params: typed<{ id: string, storyId: string }>(ConnectStoryParamsSchema) }, typed())
|
|
209
228
|
),
|
|
210
229
|
develop: protocol(
|
|
211
230
|
route(connect.story.develop, '/story/:id/:storyId/develop', {
|
|
212
|
-
parent:
|
|
231
|
+
parent: base, method: RouteMethod.POST
|
|
213
232
|
}),
|
|
214
233
|
contract.request({ params: typed<{ id: string, storyId: string }>(ConnectStoryParamsSchema) }, typed())
|
|
215
234
|
),
|
|
216
235
|
|
|
217
236
|
},
|
|
218
237
|
|
|
238
|
+
// --- generated files and conversion ----------------------------------------------------
|
|
239
|
+
files: {
|
|
240
|
+
list: protocol(
|
|
241
|
+
route(connect.files.list, '/project/:id/files', { parent: base, method: RouteMethod.GET }),
|
|
242
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<string[]>()),
|
|
243
|
+
),
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
convert: {
|
|
247
|
+
create: protocol(
|
|
248
|
+
route(connect.convert.create, '/convert', { parent: base, method: RouteMethod.POST }),
|
|
249
|
+
contract.request({ body: typed<ConnectConvertCreateBody>(ConnectConvertCreateBodySchema) }, typed<ConnectJob>()),
|
|
250
|
+
),
|
|
251
|
+
check: protocol(
|
|
252
|
+
route(connect.convert.check, '/convert/:id/check', { parent: base, method: RouteMethod.GET }),
|
|
253
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<ConvertCheck>()),
|
|
254
|
+
),
|
|
255
|
+
start: protocol(
|
|
256
|
+
route(connect.convert.start, '/convert/:id/start', { parent: base, method: RouteMethod.POST }),
|
|
257
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<ConnectJob>()),
|
|
258
|
+
),
|
|
259
|
+
proceed: protocol(
|
|
260
|
+
route(connect.convert.proceed, '/convert/:id/proceed', { parent: base, method: RouteMethod.POST }),
|
|
261
|
+
contract.request({
|
|
262
|
+
params: typed<{ id: string }>(ConnectProjectIdSchema),
|
|
263
|
+
body: typed<ConnectConvertProceedBody>(ConnectConvertProceedBodySchema),
|
|
264
|
+
}, typed<ConnectJob>()),
|
|
265
|
+
),
|
|
266
|
+
cancel: protocol(
|
|
267
|
+
route(connect.convert.cancel, '/convert/:id/cancel', { parent: base, method: RouteMethod.POST }),
|
|
268
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<ConnectJob>()),
|
|
269
|
+
),
|
|
270
|
+
status: protocol(
|
|
271
|
+
route(connect.convert.status, '/convert/:id', { parent: base, method: RouteMethod.GET }),
|
|
272
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<ConversionStatusView>()),
|
|
273
|
+
),
|
|
274
|
+
purge: protocol(
|
|
275
|
+
route(connect.convert.purge, '/convert/:id/purge', { parent: base, method: RouteMethod.POST }),
|
|
276
|
+
contract.request({ params: typed<{ id: string }>(ConnectProjectIdSchema) }, typed<ConnectJob>()),
|
|
277
|
+
),
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
inquiry: {
|
|
281
|
+
answer: protocol(
|
|
282
|
+
route(connect.inquiry.answer, '/project/:id/inquiry/:inquiryId', {
|
|
283
|
+
parent: base, method: RouteMethod.POST,
|
|
284
|
+
}),
|
|
285
|
+
contract.request({
|
|
286
|
+
params: typed<{ id: string, inquiryId: string }>(ConnectInquiryParamsSchema),
|
|
287
|
+
body: typed<ConnectInquiryAnswerBody>(InquiryAnswerSchema),
|
|
288
|
+
}, typed()),
|
|
289
|
+
),
|
|
290
|
+
},
|
|
291
|
+
|
|
219
292
|
// --- pipelines -------------------------------------------------------------------------
|
|
220
293
|
pipeline: {
|
|
221
294
|
state: protocol(
|
|
222
295
|
route(connect.pipeline.state, '/pipeline/:id/:runId', {
|
|
223
|
-
parent:
|
|
296
|
+
parent: base, method: RouteMethod.GET
|
|
224
297
|
}),
|
|
225
298
|
contract.request({ params: typed<ConnectPipelineParams>(ConnectPipelineParamsSchema) }, typed())
|
|
226
299
|
),
|
|
227
300
|
resume: protocol(
|
|
228
301
|
route(connect.pipeline.resume, '/pipeline/:id/:runId/resume', {
|
|
229
|
-
parent:
|
|
302
|
+
parent: base, method: RouteMethod.POST
|
|
230
303
|
}),
|
|
231
304
|
contract.request({ params: typed<ConnectPipelineParams>(ConnectPipelineParamsSchema), body: typed<ConnectPipelineResumeBody>(ConnectPipelineResumeBodySchema) }, typed())
|
|
232
305
|
),
|
package/src/connect/errors.ts
CHANGED
|
@@ -82,6 +82,49 @@ export class ConnectOpUnknown extends ConnectError {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* The organization cannot pay for the action a connector just asked for.
|
|
87
|
+
*
|
|
88
|
+
* Only `type` and `message` survive a marshal/unmarshal round trip, so the fields a caller needs
|
|
89
|
+
* to phrase a kind refusal — which action, how short, and where to top up — travel packed into the
|
|
90
|
+
* message and are parsed back out in `finalizeUnmarshal()`. The URL is `encodeURIComponent`-ed
|
|
91
|
+
* because it is the one field that could itself contain a colon.
|
|
92
|
+
*/
|
|
93
|
+
export class ConnectOutOfCredits extends ConnectError {
|
|
94
|
+
public static override typeName = `OutOfCredits${ConnectError.typeName}`
|
|
95
|
+
|
|
96
|
+
public gate = ''
|
|
97
|
+
public requiredUsd = 0
|
|
98
|
+
public balanceUsd = 0
|
|
99
|
+
public topUpUrl = ''
|
|
100
|
+
|
|
101
|
+
/** Build the packed message a caller passes to the constructor. */
|
|
102
|
+
static encode(gate: string, requiredUsd: number, balanceUsd: number, topUpUrl: string): string {
|
|
103
|
+
return `${gate}:${requiredUsd}:${balanceUsd}:${encodeURIComponent(topUpUrl)}`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
constructor(message: string = 'error') {
|
|
107
|
+
super(`out-of-credits:${message}`)
|
|
108
|
+
this.type = ConnectOutOfCredits.typeName
|
|
109
|
+
this.applyFields()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private applyFields(): void {
|
|
113
|
+
const marker = 'out-of-credits:'
|
|
114
|
+
const at = this.message.indexOf(marker)
|
|
115
|
+
if (at < 0) return
|
|
116
|
+
const [gate, requiredUsd, balanceUsd, encodedUrl] = this.message.slice(at + marker.length).split(':')
|
|
117
|
+
this.gate = gate ?? ''
|
|
118
|
+
this.requiredUsd = Number(requiredUsd ?? 0) || 0
|
|
119
|
+
this.balanceUsd = Number(balanceUsd ?? 0) || 0
|
|
120
|
+
this.topUpUrl = encodedUrl != null && encodedUrl !== '' ? decodeURIComponent(encodedUrl) : ''
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override finalizeUnmarshal(): void {
|
|
124
|
+
this.applyFields()
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
85
128
|
ResilientError.registerErrorClass(ConnectError)
|
|
86
129
|
ResilientError.registerErrorClass(ConnectSessionNotFound)
|
|
87
130
|
ResilientError.registerErrorClass(ConnectSessionGone)
|
|
@@ -89,3 +132,4 @@ ResilientError.registerErrorClass(ConnectOpTimeout)
|
|
|
89
132
|
ResilientError.registerErrorClass(ConnectOpRefused)
|
|
90
133
|
ResilientError.registerErrorClass(LocalSlotUnsupported)
|
|
91
134
|
ResilientError.registerErrorClass(ConnectOpUnknown)
|
|
135
|
+
ResilientError.registerErrorClass(ConnectOutOfCredits)
|
package/src/connect/ops.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SlotCommandPayload } from '../slot/index.js'
|
|
2
2
|
import type {
|
|
3
|
-
ConnectOpErrorKind, ConnectOpKind, ModelTaskMode, ModelTaskResultKind,
|
|
3
|
+
ConnectInquiryKind, ConnectOpErrorKind, ConnectOpKind, ModelTaskMode, ModelTaskResultKind,
|
|
4
|
+
ModelTaskRole, ModelTier
|
|
4
5
|
} from './consts.js'
|
|
5
6
|
import type { ConnectServices } from './types.js'
|
|
6
7
|
|
|
@@ -17,7 +18,7 @@ export interface ConnectOp {
|
|
|
17
18
|
projectId: string
|
|
18
19
|
sessionId: string
|
|
19
20
|
kind: ConnectOpKind
|
|
20
|
-
payload: SlotCommandPayload | ModelTask | ConfigurePayload
|
|
21
|
+
payload: SlotCommandPayload | ModelTask | ConfigurePayload | InquiryPayload
|
|
21
22
|
createdAt: string
|
|
22
23
|
/** When the asker stops waiting. A connector past this may skip the work and say so. */
|
|
23
24
|
deadlineAt: string
|
|
@@ -158,3 +159,50 @@ export interface ModelTaskUsage {
|
|
|
158
159
|
inputTokens?: number
|
|
159
160
|
outputTokens?: number
|
|
160
161
|
}
|
|
162
|
+
|
|
163
|
+
/** One option a {@link ConnectInquiryKind.Choice} question offers. */
|
|
164
|
+
export interface ConnectInquiryOption {
|
|
165
|
+
value: string
|
|
166
|
+
label: string
|
|
167
|
+
description?: string
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* One question put to the person the connector is working for.
|
|
172
|
+
*
|
|
173
|
+
* It carries where it came from — the job, the run and the step — because an answer is recorded
|
|
174
|
+
* against the run that asked and re-read when that run resumes. `expiresAt` is what makes an
|
|
175
|
+
* unanswered question fail its step instead of parking a project lock forever.
|
|
176
|
+
*/
|
|
177
|
+
export interface InquiryPayload {
|
|
178
|
+
id: string
|
|
179
|
+
projectId: string
|
|
180
|
+
jobId?: string
|
|
181
|
+
runId?: string
|
|
182
|
+
/** The pipeline step that asked, so a resumed run can match the answer to the place it belongs. */
|
|
183
|
+
step?: string
|
|
184
|
+
kind: ConnectInquiryKind
|
|
185
|
+
question: string
|
|
186
|
+
/** What the asker already knows, so the person is not asked to go and find it out. */
|
|
187
|
+
context?: string
|
|
188
|
+
options?: ConnectInquiryOption[]
|
|
189
|
+
multiple?: boolean
|
|
190
|
+
/** Whether a choice question also accepts text the options do not cover. */
|
|
191
|
+
allowText?: boolean
|
|
192
|
+
/** What the asker will assume if nobody answers. Recorded as an assumption when it is used. */
|
|
193
|
+
default?: string | string[]
|
|
194
|
+
expiresAt: string
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The answer to one question.
|
|
199
|
+
*
|
|
200
|
+
* `declined` is a real answer and not an absence: it says a person saw the question and chose not
|
|
201
|
+
* to decide, which the asker records as an assumption rather than waiting out the timeout.
|
|
202
|
+
*/
|
|
203
|
+
export interface InquiryAnswerPayload {
|
|
204
|
+
inquiryId: string
|
|
205
|
+
value?: string | string[]
|
|
206
|
+
text?: string
|
|
207
|
+
declined?: boolean
|
|
208
|
+
}
|