@proteos/sdk 0.54.1 → 0.55.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.
- package/dist/{chunk-QUCSWC3M.cjs → chunk-3UBIL3WV.cjs} +37 -2
- package/dist/chunk-3UBIL3WV.cjs.map +1 -0
- package/dist/{chunk-B2EZDFFH.js → chunk-WJYUQBEG.js} +34 -3
- package/dist/chunk-WJYUQBEG.js.map +1 -0
- package/dist/index.cjs +139 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +251 -39
- package/dist/index.d.ts +251 -39
- package/dist/index.js +24 -2
- package/dist/index.js.map +1 -1
- package/dist/meta/index.cjs +91 -75
- package/dist/meta/index.d.cts +1 -1
- package/dist/meta/index.d.ts +1 -1
- package/dist/meta/index.js +1 -1
- package/dist/{types-6-ywikNl.d.cts → types-CylP2A4p.d.cts} +23 -1
- package/dist/{types-6-ywikNl.d.ts → types-CylP2A4p.d.ts} +23 -1
- package/package.json +1 -1
- package/src/agent/index.ts +42 -6
- package/src/agent/model-types.ts +193 -0
- package/src/agent/models.ts +67 -0
- package/src/index.ts +20 -1
- package/src/meta/index.ts +6 -0
- package/src/meta/record-title.ts +50 -0
- package/src/workflow/types.ts +3 -1
- package/dist/chunk-B2EZDFFH.js.map +0 -1
- package/dist/chunk-QUCSWC3M.cjs.map +0 -1
package/src/agent/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ProteosClient } from '../client.js'
|
|
2
2
|
import { type AgentService, AgentServiceImpl } from './agents.js'
|
|
3
3
|
import { type McpServerService, McpServerServiceImpl } from './mcp-servers.js'
|
|
4
|
+
import { type ModelService, ModelServiceImpl } from './models.js'
|
|
4
5
|
import { type PromptService, PromptServiceImpl } from './prompts.js'
|
|
5
6
|
import { type SessionService, SessionServiceImpl } from './sessions.js'
|
|
6
7
|
import { type SkillService, SkillServiceImpl } from './skills.js'
|
|
@@ -12,7 +13,8 @@ import { type ToolsetService, ToolsetServiceImpl } from './toolsets.js'
|
|
|
12
13
|
*
|
|
13
14
|
* Manages the AI-agent configuration domain: Agents, Prompts (versioned),
|
|
14
15
|
* Skills (versioned bundles), Tools, and MCP Servers — all org-scoped and keyed
|
|
15
|
-
* by an immutable kebab-case `key
|
|
16
|
+
* by an immutable kebab-case `key` — plus the stateless model calls
|
|
17
|
+
* (`models.generate`, `models.decide`) and chat sessions.
|
|
16
18
|
*
|
|
17
19
|
* @example
|
|
18
20
|
* ```ts
|
|
@@ -23,6 +25,15 @@ import { type ToolsetService, ToolsetServiceImpl } from './toolsets.js'
|
|
|
23
25
|
*
|
|
24
26
|
* const agents = await agent.agents.list().all();
|
|
25
27
|
* const prompt = await agent.prompts.get('revenue-brief');
|
|
28
|
+
*
|
|
29
|
+
* const { answers } = await agent.models.decide({
|
|
30
|
+
* state: { message: 'My card was charged twice!' },
|
|
31
|
+
* questions: {
|
|
32
|
+
* refund_requested: { type: 'boolean', instructions: 'Does the customer ask for money back?' },
|
|
33
|
+
* topic: { type: 'choice', instructions: 'Topic?', criteria: { billing: 'charges', other: 'else' } },
|
|
34
|
+
* },
|
|
35
|
+
* });
|
|
36
|
+
* if (answers.topic.confidence > 0.8) route(answers.topic.choice);
|
|
26
37
|
* ```
|
|
27
38
|
*/
|
|
28
39
|
export class AgentClient {
|
|
@@ -38,6 +49,8 @@ export class AgentClient {
|
|
|
38
49
|
readonly toolsets: ToolsetService
|
|
39
50
|
/** Service for managing MCP server registrations. */
|
|
40
51
|
readonly mcpServers: McpServerService
|
|
52
|
+
/** Service for stateless model calls: `generate` (one message out) and `decide` (calibrated typed answers). */
|
|
53
|
+
readonly models: ModelService
|
|
41
54
|
/** Service for managing chat sessions (conversations + event log + stream). */
|
|
42
55
|
readonly sessions: SessionService
|
|
43
56
|
|
|
@@ -53,6 +66,7 @@ export class AgentClient {
|
|
|
53
66
|
this.tools = new ToolServiceImpl(client)
|
|
54
67
|
this.toolsets = new ToolsetServiceImpl(client)
|
|
55
68
|
this.mcpServers = new McpServerServiceImpl(client)
|
|
69
|
+
this.models = new ModelServiceImpl(client)
|
|
56
70
|
this.sessions = new SessionServiceImpl(client)
|
|
57
71
|
}
|
|
58
72
|
}
|
|
@@ -60,6 +74,28 @@ export class AgentClient {
|
|
|
60
74
|
// Re-export service interfaces
|
|
61
75
|
export type { AgentService } from './agents.js'
|
|
62
76
|
export type { McpServerService } from './mcp-servers.js'
|
|
77
|
+
// Re-export model-call types (generate + decide)
|
|
78
|
+
export type {
|
|
79
|
+
BooleanAnswer,
|
|
80
|
+
BooleanCriteria,
|
|
81
|
+
BooleanQuestion,
|
|
82
|
+
ChoiceAnswer,
|
|
83
|
+
ChoiceQuestion,
|
|
84
|
+
DecideRequest,
|
|
85
|
+
DecisionAnswer,
|
|
86
|
+
DecisionAnswerFor,
|
|
87
|
+
DecisionQuestion,
|
|
88
|
+
DecisionQuestions,
|
|
89
|
+
DecisionQuestionType,
|
|
90
|
+
DecisionResult,
|
|
91
|
+
GenerateRequest,
|
|
92
|
+
GenerationResult,
|
|
93
|
+
ModelStopReason,
|
|
94
|
+
ScoreAnswer,
|
|
95
|
+
ScoreQuestion,
|
|
96
|
+
StructuredText,
|
|
97
|
+
} from './model-types.js'
|
|
98
|
+
export type { ModelService } from './models.js'
|
|
63
99
|
export type { PromptService } from './prompts.js'
|
|
64
100
|
// Re-export session types
|
|
65
101
|
export type {
|
|
@@ -110,12 +146,14 @@ export type {
|
|
|
110
146
|
CreateMcpServerRequest,
|
|
111
147
|
CreatePromptRequest,
|
|
112
148
|
CreateToolRequest,
|
|
149
|
+
CreateToolsetRequest,
|
|
113
150
|
DependentAgent,
|
|
114
151
|
DependentSyncResult,
|
|
115
152
|
ListAgentsOptions,
|
|
116
153
|
ListMcpServersOptions,
|
|
117
154
|
ListPromptsOptions,
|
|
118
155
|
ListSkillsOptions,
|
|
156
|
+
ListToolsetsOptions,
|
|
119
157
|
ListToolsOptions,
|
|
120
158
|
McpBinding,
|
|
121
159
|
McpConnectionState,
|
|
@@ -125,25 +163,23 @@ export type {
|
|
|
125
163
|
McpServerOAuth,
|
|
126
164
|
McpToolSummary,
|
|
127
165
|
ModelConfig,
|
|
166
|
+
PlatformBinding,
|
|
128
167
|
Prompt,
|
|
129
168
|
PromptVersion,
|
|
169
|
+
QueryBinding,
|
|
130
170
|
Skill,
|
|
131
171
|
SkillBundle,
|
|
132
172
|
SkillVersion,
|
|
133
173
|
StartMcpOAuthResponse,
|
|
134
|
-
PlatformBinding,
|
|
135
|
-
QueryBinding,
|
|
136
174
|
Tool,
|
|
137
175
|
ToolBinding,
|
|
138
176
|
ToolKind,
|
|
139
177
|
Toolset,
|
|
140
178
|
ToolsetKind,
|
|
141
179
|
ToolsetToolSummary,
|
|
142
|
-
CreateToolsetRequest,
|
|
143
|
-
UpdateToolsetRequest,
|
|
144
|
-
ListToolsetsOptions,
|
|
145
180
|
UpdateAgentRequest,
|
|
146
181
|
UpdateMcpServerRequest,
|
|
147
182
|
UpdatePromptRequest,
|
|
148
183
|
UpdateToolRequest,
|
|
184
|
+
UpdateToolsetRequest,
|
|
149
185
|
} from './types.js'
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the stateless model endpoints of the Proteos Agent Service API —
|
|
3
|
+
* `POST /agents/v1/models/generate` and `POST /agents/v1/models/decide`.
|
|
4
|
+
*
|
|
5
|
+
* Hand-written mirror of the Go models in `go.proteos.ai/model/agent`
|
|
6
|
+
* (`generation.go`, `decision.go` + `api/generation-requests.go`,
|
|
7
|
+
* `api/decision-requests.go`). Field names match the snake_case wire format
|
|
8
|
+
* exactly, including enum values.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ContentBlock, ModelUsage, TextBlock } from './session-types.js'
|
|
12
|
+
import type { ModelConfig } from './types.js'
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Generation (one message out)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Why the model stopped generating. An open string so a new provider reason
|
|
20
|
+
* never breaks decoding; the key distinction is `end_turn` (complete) vs
|
|
21
|
+
* `max_tokens` (truncated).
|
|
22
|
+
*/
|
|
23
|
+
export type ModelStopReason = 'end_turn' | 'max_tokens' | 'stop_sequence' | (string & {})
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Body of `POST /agents/v1/models/generate` — a single, stateless model call:
|
|
27
|
+
* content blocks in, one assistant message out. No event log, no tools, no
|
|
28
|
+
* multi-turn state.
|
|
29
|
+
*/
|
|
30
|
+
export interface GenerateRequest {
|
|
31
|
+
/** Model id + sampling knobs. Omitted (or an empty `model_id`) resolves to the service default. */
|
|
32
|
+
model?: Partial<ModelConfig>
|
|
33
|
+
/** Optional system prompt steering the response. */
|
|
34
|
+
system?: string
|
|
35
|
+
/** The message body the model answers — text and file blocks (a file-only body is valid). */
|
|
36
|
+
content: ContentBlock[]
|
|
37
|
+
/**
|
|
38
|
+
* JSON Schema of the structured reply. When set, generation is forced through a
|
|
39
|
+
* schema-constrained tool and the structured value comes back as `output`.
|
|
40
|
+
*/
|
|
41
|
+
output_schema?: Record<string, unknown>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** The assistant's reply to a {@link GenerateRequest}. */
|
|
45
|
+
export interface GenerationResult {
|
|
46
|
+
/** The returned text blocks (usually empty on a schema-constrained call). */
|
|
47
|
+
content: TextBlock[]
|
|
48
|
+
stop_reason?: ModelStopReason
|
|
49
|
+
/** The model that produced the reply (resolved id). */
|
|
50
|
+
model_id: string
|
|
51
|
+
usage: ModelUsage
|
|
52
|
+
/** The structured value of a schema-constrained generation; absent otherwise. */
|
|
53
|
+
output?: unknown
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Decisions (typed, calibrated answers out — no prose)
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The text shape a decision provider reads: a string, a JSON object, or an
|
|
62
|
+
* array — never `null`, a number, or a boolean. Carries the state under
|
|
63
|
+
* judgment, a question's instructions, every criteria description, and the
|
|
64
|
+
* legend echoed back on a score. Structure passes through verbatim, so
|
|
65
|
+
* instructions can be structured guidance (named fields such as `what` /
|
|
66
|
+
* `not_for` / `examples`, backtick paths into the state like
|
|
67
|
+
* `` `ticket.messages[0].text` ``).
|
|
68
|
+
*/
|
|
69
|
+
export type StructuredText = string | Record<string, unknown> | unknown[]
|
|
70
|
+
|
|
71
|
+
/** Discriminates a {@link DecisionQuestion} and its {@link DecisionAnswer}. */
|
|
72
|
+
export type DecisionQuestionType = 'boolean' | 'choice' | 'score'
|
|
73
|
+
|
|
74
|
+
/** Describes the two outcomes of a {@link BooleanQuestion}. */
|
|
75
|
+
export interface BooleanCriteria {
|
|
76
|
+
true: StructuredText
|
|
77
|
+
false: StructuredText
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* "Is this statement true?" — answered with the calibrated probability that it
|
|
82
|
+
* is. `criteria` optionally spells out what makes the statement hold (true) or
|
|
83
|
+
* not (false) when the boundary is subtle.
|
|
84
|
+
*/
|
|
85
|
+
export interface BooleanQuestion {
|
|
86
|
+
type: 'boolean'
|
|
87
|
+
instructions: StructuredText
|
|
88
|
+
criteria?: BooleanCriteria
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* "Which one of these?" — `criteria` maps each option name to its description;
|
|
93
|
+
* options are unordered. Option-count limits are the provider's.
|
|
94
|
+
*/
|
|
95
|
+
export interface ChoiceQuestion<Option extends string = string> {
|
|
96
|
+
type: 'choice'
|
|
97
|
+
instructions: StructuredText
|
|
98
|
+
criteria: Record<Option, StructuredText>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* "Where on this scale?" — `criteria` is the ordered list of level
|
|
103
|
+
* descriptions; the level number is the position (0-based). Every level must
|
|
104
|
+
* be described. Level-count limits are the provider's.
|
|
105
|
+
*/
|
|
106
|
+
export interface ScoreQuestion {
|
|
107
|
+
type: 'score'
|
|
108
|
+
instructions: StructuredText
|
|
109
|
+
criteria: StructuredText[]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** One atomic question over the shared state, discriminated by `type`. */
|
|
113
|
+
export type DecisionQuestion = BooleanQuestion | ChoiceQuestion | ScoreQuestion
|
|
114
|
+
|
|
115
|
+
/** Caller-keyed questions; answers come back under the same keys. */
|
|
116
|
+
export type DecisionQuestions = Record<string, DecisionQuestion>
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Body of `POST /agents/v1/models/decide` — one text-only state and a map of
|
|
120
|
+
* atomic questions answered in parallel with calibrated probabilities.
|
|
121
|
+
*
|
|
122
|
+
* Only `model.model_id` is meaningful for a decision; the sampling knobs of
|
|
123
|
+
* {@link ModelConfig} are rejected with `invalid_decision_request`.
|
|
124
|
+
*/
|
|
125
|
+
export interface DecideRequest<Questions extends DecisionQuestions = DecisionQuestions> {
|
|
126
|
+
model?: Partial<Pick<ModelConfig, 'model_id'>>
|
|
127
|
+
state: StructuredText
|
|
128
|
+
questions: Questions
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Answer to a {@link BooleanQuestion}: `probability` is P(true); `boolean` is
|
|
133
|
+
* the argmax (probability > 0.5); `confidence` is |2p − 1|.
|
|
134
|
+
*/
|
|
135
|
+
export interface BooleanAnswer {
|
|
136
|
+
type: 'boolean'
|
|
137
|
+
boolean: boolean
|
|
138
|
+
probability: number
|
|
139
|
+
confidence: number
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Answer to a {@link ChoiceQuestion}: `choice` is the highest-probability
|
|
144
|
+
* option; `probabilities` is the full distribution keyed by option name.
|
|
145
|
+
*/
|
|
146
|
+
export interface ChoiceAnswer<Option extends string = string> {
|
|
147
|
+
type: 'choice'
|
|
148
|
+
choice: Option
|
|
149
|
+
probabilities: Record<Option, number>
|
|
150
|
+
confidence: number
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Answer to a {@link ScoreQuestion}: `score` is the probability-weighted mean
|
|
155
|
+
* of the level numbers (so it can fall between levels); `legend` echoes the
|
|
156
|
+
* level descriptions and `probabilities` the distribution, both indexed by
|
|
157
|
+
* level.
|
|
158
|
+
*/
|
|
159
|
+
export interface ScoreAnswer {
|
|
160
|
+
type: 'score'
|
|
161
|
+
score: number
|
|
162
|
+
legend: StructuredText[]
|
|
163
|
+
probabilities: number[]
|
|
164
|
+
confidence: number
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* The calibrated answer to one question, discriminated by `type`. Every
|
|
169
|
+
* variant carries `confidence` = (n·peak − 1)/(n − 1) over its distribution,
|
|
170
|
+
* so gating code can threshold without switching on the type.
|
|
171
|
+
*/
|
|
172
|
+
export type DecisionAnswer = BooleanAnswer | ChoiceAnswer | ScoreAnswer
|
|
173
|
+
|
|
174
|
+
/** The answer type a given question produces (drives typed `answers`). */
|
|
175
|
+
export type DecisionAnswerFor<Question extends DecisionQuestion> = Question extends BooleanQuestion
|
|
176
|
+
? BooleanAnswer
|
|
177
|
+
: Question extends ChoiceQuestion<infer Option>
|
|
178
|
+
? ChoiceAnswer<Option>
|
|
179
|
+
: Question extends ScoreQuestion
|
|
180
|
+
? ScoreAnswer
|
|
181
|
+
: never
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The provider's reply to a {@link DecideRequest}: one answer per question key
|
|
185
|
+
* (typed from the questions you sent), the model that produced them, and token
|
|
186
|
+
* usage.
|
|
187
|
+
*/
|
|
188
|
+
export interface DecisionResult<Questions extends DecisionQuestions = DecisionQuestions> {
|
|
189
|
+
/** The model that produced the answers (resolved id, e.g. `jev-1.13.0`). */
|
|
190
|
+
model_id: string
|
|
191
|
+
answers: { [Key in keyof Questions]: DecisionAnswerFor<Questions[Key]> }
|
|
192
|
+
usage: ModelUsage
|
|
193
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ProteosClient } from '../client.js'
|
|
2
|
+
import type {
|
|
3
|
+
DecideRequest,
|
|
4
|
+
DecisionQuestions,
|
|
5
|
+
DecisionResult,
|
|
6
|
+
GenerateRequest,
|
|
7
|
+
GenerationResult,
|
|
8
|
+
} from './model-types.js'
|
|
9
|
+
|
|
10
|
+
const MODELS_BASE_PATH = '/agents/v1/models'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Service for the stateless model calls — one request in, one reply out, no
|
|
14
|
+
* session, no event log:
|
|
15
|
+
*
|
|
16
|
+
* - `generate` — free text or schema-constrained structured output from an LLM.
|
|
17
|
+
* - `decide` — calibrated typed answers (boolean | choice | score) with
|
|
18
|
+
* probabilities and confidence, for snap judgments inside code paths
|
|
19
|
+
* (routing, triage, classification, gates). No prose comes back; compose the
|
|
20
|
+
* answers in code and threshold on `confidence`.
|
|
21
|
+
*
|
|
22
|
+
* Both need the `agent-sessions:write` permission.
|
|
23
|
+
*/
|
|
24
|
+
export interface ModelService {
|
|
25
|
+
/**
|
|
26
|
+
* Runs a single model call and returns the assistant message.
|
|
27
|
+
* @throws {ProteosError} 400 `invalid_generation_request` / `unsupported_file_type` /
|
|
28
|
+
* `model_provider_rejected_request`; 429 `model_provider_rate_limited`;
|
|
29
|
+
* 502 `model_provider_failed`.
|
|
30
|
+
*/
|
|
31
|
+
generate(request: GenerateRequest): Promise<GenerationResult>
|
|
32
|
+
/**
|
|
33
|
+
* Answers typed questions about a text state with calibrated probabilities.
|
|
34
|
+
* `answers` is typed from the `questions` you pass, so
|
|
35
|
+
* `result.answers.topic.choice` narrows to the option names you declared.
|
|
36
|
+
*
|
|
37
|
+
* Semantic limits (option / level counts, empty questions, unknown model ids)
|
|
38
|
+
* are the provider's and surface as `decision_provider_rejected_request` with
|
|
39
|
+
* its message.
|
|
40
|
+
* @throws {ProteosError} 400 `invalid_decision_request` (shape) /
|
|
41
|
+
* `decision_provider_rejected_request` (provider rule); 429
|
|
42
|
+
* `decision_provider_rate_limited`; 502 `decision_provider_failed` /
|
|
43
|
+
* `decision_provider_invalid_response`; 503 `decision_provider_unavailable`
|
|
44
|
+
* when the provider key is not configured.
|
|
45
|
+
*/
|
|
46
|
+
decide<Questions extends DecisionQuestions>(
|
|
47
|
+
request: DecideRequest<Questions>,
|
|
48
|
+
): Promise<DecisionResult<Questions>>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class ModelServiceImpl implements ModelService {
|
|
52
|
+
constructor(private readonly client: ProteosClient) {}
|
|
53
|
+
|
|
54
|
+
async generate(request: GenerateRequest): Promise<GenerationResult> {
|
|
55
|
+
return this.client.request<GenerationResult>('POST', `${MODELS_BASE_PATH}/generate`, request)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async decide<Questions extends DecisionQuestions>(
|
|
59
|
+
request: DecideRequest<Questions>,
|
|
60
|
+
): Promise<DecisionResult<Questions>> {
|
|
61
|
+
return this.client.request<DecisionResult<Questions>>(
|
|
62
|
+
'POST',
|
|
63
|
+
`${MODELS_BASE_PATH}/decide`,
|
|
64
|
+
request,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* @packageDocumentation
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
// Agent client (agent-service: agents, prompts, skills, tools, mcp-servers, sessions)
|
|
37
|
+
// Agent client (agent-service: agents, prompts, skills, tools, mcp-servers, models, sessions)
|
|
38
38
|
export type {
|
|
39
39
|
ActionBinding,
|
|
40
40
|
Agent,
|
|
@@ -43,6 +43,11 @@ export type {
|
|
|
43
43
|
AgentResourceListOptions,
|
|
44
44
|
AgentService,
|
|
45
45
|
AppendEventRequest,
|
|
46
|
+
BooleanAnswer,
|
|
47
|
+
BooleanCriteria,
|
|
48
|
+
BooleanQuestion,
|
|
49
|
+
ChoiceAnswer,
|
|
50
|
+
ChoiceQuestion,
|
|
46
51
|
ClientEventType,
|
|
47
52
|
ClientToolSchema,
|
|
48
53
|
ContentBlock,
|
|
@@ -53,12 +58,21 @@ export type {
|
|
|
53
58
|
CreateSessionRequest,
|
|
54
59
|
CreateToolRequest,
|
|
55
60
|
CreateToolsetRequest,
|
|
61
|
+
DecideRequest,
|
|
62
|
+
DecisionAnswer,
|
|
63
|
+
DecisionAnswerFor,
|
|
64
|
+
DecisionQuestion,
|
|
65
|
+
DecisionQuestions,
|
|
66
|
+
DecisionQuestionType,
|
|
67
|
+
DecisionResult,
|
|
56
68
|
DependentAgent,
|
|
57
69
|
DependentSyncResult,
|
|
58
70
|
EmptyPayload,
|
|
59
71
|
ErrorPayload,
|
|
60
72
|
EventType,
|
|
61
73
|
FileBlock,
|
|
74
|
+
GenerateRequest,
|
|
75
|
+
GenerationResult,
|
|
62
76
|
ListAgentsOptions,
|
|
63
77
|
ListMcpServersOptions,
|
|
64
78
|
ListPromptsOptions,
|
|
@@ -77,6 +91,8 @@ export type {
|
|
|
77
91
|
ModelConfig,
|
|
78
92
|
ModelRequestEndPayload,
|
|
79
93
|
ModelRequestStartPayload,
|
|
94
|
+
ModelService,
|
|
95
|
+
ModelStopReason,
|
|
80
96
|
ModelUsage,
|
|
81
97
|
PlatformBinding,
|
|
82
98
|
Prompt,
|
|
@@ -85,6 +101,8 @@ export type {
|
|
|
85
101
|
QueryBinding,
|
|
86
102
|
ReasoningPayload,
|
|
87
103
|
ResultBlock,
|
|
104
|
+
ScoreAnswer,
|
|
105
|
+
ScoreQuestion,
|
|
88
106
|
Session,
|
|
89
107
|
SessionEvent,
|
|
90
108
|
SessionEventEnvelope,
|
|
@@ -100,6 +118,7 @@ export type {
|
|
|
100
118
|
SkillVersion,
|
|
101
119
|
StartMcpOAuthResponse,
|
|
102
120
|
StopReason,
|
|
121
|
+
StructuredText,
|
|
103
122
|
TextBlock,
|
|
104
123
|
Tool,
|
|
105
124
|
ToolBinding,
|
package/src/meta/index.ts
CHANGED
|
@@ -164,6 +164,12 @@ export type { MenuConfigurationService } from './menu-configurations.js'
|
|
|
164
164
|
export type { ModuleService } from './modules.js'
|
|
165
165
|
export type { PageExtensionService } from './page-extensions.js'
|
|
166
166
|
export type { PageService } from './pages.js'
|
|
167
|
+
export {
|
|
168
|
+
isReservedAttributeName,
|
|
169
|
+
isTitleQueryable,
|
|
170
|
+
RECORD_TITLE_FIELD,
|
|
171
|
+
titleTemplateVariables,
|
|
172
|
+
} from './record-title.js'
|
|
167
173
|
// Re-export types
|
|
168
174
|
export type {
|
|
169
175
|
// App types
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The virtual column that stands for a record's rendered title — the entity's
|
|
3
|
+
* Liquid `title_template` evaluated against the row. Lists show it, and the
|
|
4
|
+
* records query sorts and filters on it when the template is "simple". No
|
|
5
|
+
* attribute backs it, so the name is reserved: the backend rejects an
|
|
6
|
+
* attribute called `record_title` (mirror of `metamodel.RecordTitleField`).
|
|
7
|
+
*/
|
|
8
|
+
export const RECORD_TITLE_FIELD = 'record_title'
|
|
9
|
+
|
|
10
|
+
/** True when `name` is taken by a virtual column and unavailable to attributes. */
|
|
11
|
+
export function isReservedAttributeName(name: string): boolean {
|
|
12
|
+
return name === RECORD_TITLE_FIELD
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A simple template is literal text plus `{{ attribute }}` references and
|
|
17
|
+
* nothing else — no filters (`| upcase`), no tags (`{% if %}`), no dotted
|
|
18
|
+
* references. Only those compile to SQL, so only those make `record_title`
|
|
19
|
+
* sortable and filterable. Mirror of the Go `titletemplate.ParseSimple`
|
|
20
|
+
* grammar; the backend stays the authority and answers 400 when the two
|
|
21
|
+
* ever disagree.
|
|
22
|
+
*/
|
|
23
|
+
export function isTitleQueryable(template: string | undefined): boolean {
|
|
24
|
+
// Nothing to order or match on without at least one attribute reference.
|
|
25
|
+
if (!template?.includes('{{')) return false
|
|
26
|
+
if (template.includes('{%') || template.includes('%}')) return false
|
|
27
|
+
let rest = template
|
|
28
|
+
while (rest !== '') {
|
|
29
|
+
const open = rest.indexOf('{{')
|
|
30
|
+
if (open < 0) return !rest.includes('}}')
|
|
31
|
+
if (rest.slice(0, open).includes('}}')) return false
|
|
32
|
+
rest = rest.slice(open + 2)
|
|
33
|
+
const close = rest.indexOf('}}')
|
|
34
|
+
if (close < 0) return false
|
|
35
|
+
if (!/^[a-z][a-z0-9_]*$/.test(rest.slice(0, close).trim())) return false
|
|
36
|
+
rest = rest.slice(close + 2)
|
|
37
|
+
}
|
|
38
|
+
return true
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The attributes a simple template references, in order of first use; `[]` otherwise. */
|
|
42
|
+
export function titleTemplateVariables(template: string | undefined): string[] {
|
|
43
|
+
if (!template || !isTitleQueryable(template)) return []
|
|
44
|
+
const out: string[] = []
|
|
45
|
+
for (const match of template.matchAll(/\{\{\s*([a-z][a-z0-9_]*)\s*\}\}/g)) {
|
|
46
|
+
const name = match[1]
|
|
47
|
+
if (name && !out.includes(name)) out.push(name)
|
|
48
|
+
}
|
|
49
|
+
return out
|
|
50
|
+
}
|
package/src/workflow/types.ts
CHANGED
|
@@ -165,7 +165,9 @@ export type PropertyType =
|
|
|
165
165
|
| 'credentials_select'
|
|
166
166
|
| 'button'
|
|
167
167
|
/** Edits a platform attribute list (`Attribute[]`) via the shared attribute schema builder. */
|
|
168
|
-
|
|
168
|
+
/** Edits a decision-question map (model-decide `questions`) via the questions builder, with a raw-JSON mode. */
|
|
169
|
+
| 'decision_questions'
|
|
170
|
+
| 'attribute_schema'
|
|
169
171
|
// Wave 2 (editor support lands with Phase 3):
|
|
170
172
|
| 'resource_locator'
|
|
171
173
|
| 'resource_mapper'
|