@getfamiliar/shared 0.1.2
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/build/AgentRun.d.ts +187 -0
- package/build/AgentRun.js +1 -0
- package/build/AgentRunBus.d.ts +147 -0
- package/build/AgentRunBus.js +362 -0
- package/build/Calendar.d.ts +450 -0
- package/build/Calendar.js +37 -0
- package/build/ChatMessage.d.ts +53 -0
- package/build/ChatMessage.js +11 -0
- package/build/ChatMessageBus.d.ts +110 -0
- package/build/ChatMessageBus.js +257 -0
- package/build/Config.d.ts +83 -0
- package/build/Config.js +1 -0
- package/build/ContainerTool.d.ts +34 -0
- package/build/ContainerTool.js +1 -0
- package/build/CronExpression.d.ts +53 -0
- package/build/CronExpression.js +77 -0
- package/build/Event.d.ts +280 -0
- package/build/Event.js +14 -0
- package/build/EventBus.d.ts +198 -0
- package/build/EventBus.js +482 -0
- package/build/HandlerCatalog.d.ts +75 -0
- package/build/HandlerCatalog.js +165 -0
- package/build/InferenceEvent.d.ts +30 -0
- package/build/InferenceEvent.js +1 -0
- package/build/InferenceEventBus.d.ts +39 -0
- package/build/InferenceEventBus.js +80 -0
- package/build/Mail.d.ts +250 -0
- package/build/Mail.js +73 -0
- package/build/MailStyleTemplate.d.ts +71 -0
- package/build/MailStyleTemplate.js +47 -0
- package/build/ModelMetaData.d.ts +63 -0
- package/build/ModelMetaData.js +12 -0
- package/build/PathGlob.d.ts +20 -0
- package/build/PathGlob.js +33 -0
- package/build/Plugin.d.ts +709 -0
- package/build/Plugin.js +29 -0
- package/build/PostgresConnection.d.ts +75 -0
- package/build/PostgresConnection.js +162 -0
- package/build/ScheduledSubagent.d.ts +49 -0
- package/build/ScheduledSubagent.js +1 -0
- package/build/ScheduledSubagentBus.d.ts +94 -0
- package/build/ScheduledSubagentBus.js +187 -0
- package/build/Schema.d.ts +84 -0
- package/build/Schema.js +570 -0
- package/build/StepResult.d.ts +103 -0
- package/build/StepResult.js +1 -0
- package/build/StepResultBus.d.ts +64 -0
- package/build/StepResultBus.js +169 -0
- package/build/Timezone.d.ts +58 -0
- package/build/Timezone.js +84 -0
- package/build/ToolCall.d.ts +25 -0
- package/build/ToolCall.js +1 -0
- package/build/ToolCallBus.d.ts +65 -0
- package/build/ToolCallBus.js +110 -0
- package/build/ToolLevel.d.ts +20 -0
- package/build/ToolLevel.js +2 -0
- package/build/ToolRunner.d.ts +118 -0
- package/build/ToolRunner.js +192 -0
- package/build/ToolsExpressionUtils.d.ts +80 -0
- package/build/ToolsExpressionUtils.js +102 -0
- package/build/WorkspaceFile.d.ts +104 -0
- package/build/WorkspaceFile.js +7 -0
- package/build/estimateTokens.d.ts +16 -0
- package/build/estimateTokens.js +18 -0
- package/build/index.d.ts +37 -0
- package/build/index.js +26 -0
- package/build/logging/Logger.d.ts +66 -0
- package/build/logging/Logger.js +90 -0
- package/build/markdownHtml.d.ts +14 -0
- package/build/markdownHtml.js +21 -0
- package/build/markdownTerminal.d.ts +14 -0
- package/build/markdownTerminal.js +376 -0
- package/build/testing/MockAgentRunBus.d.ts +52 -0
- package/build/testing/MockAgentRunBus.js +175 -0
- package/build/testing/MockBusStore.d.ts +22 -0
- package/build/testing/MockBusStore.js +22 -0
- package/build/testing/MockEventBus.d.ts +20 -0
- package/build/testing/MockEventBus.js +57 -0
- package/build/testing/MockLogger.d.ts +52 -0
- package/build/testing/MockLogger.js +65 -0
- package/build/testing/index.d.ts +4 -0
- package/build/testing/index.js +4 -0
- package/package.json +63 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { AGENTRUNS_CHANNEL, EVENT_TERMINAL_UPDATE_SQL, SCHEMA_SQL } from "./Schema.js";
|
|
2
|
+
/**
|
|
3
|
+
* Domain client for the `agentruns` table — the assistant's response
|
|
4
|
+
* tree. Each row is one agent invocation that responds to (or descends
|
|
5
|
+
* from) an `events` row.
|
|
6
|
+
*
|
|
7
|
+
* Uses an injected {@link PostgresConnection} for pool + LISTEN access;
|
|
8
|
+
* does not own connection lifecycle.
|
|
9
|
+
*
|
|
10
|
+
* The bus is purely a CRUD surface — no claim queue, no in-process
|
|
11
|
+
* blocking primitive. The {@link import("@getfamiliar/container").AgentrunScheduler}
|
|
12
|
+
* is the sole authority on which row runs next and is guaranteed
|
|
13
|
+
* singleton inside the container, so a postgres-side claim queue
|
|
14
|
+
* (`FOR UPDATE SKIP LOCKED`) would be overkill. The Scheduler reads
|
|
15
|
+
* eligible pending rows via {@link listEligible} and writes lifecycle
|
|
16
|
+
* transitions via {@link update} / {@link settle} / {@link postpone}.
|
|
17
|
+
*
|
|
18
|
+
* The terminal write goes through {@link settle}, which transitions the
|
|
19
|
+
* agentrun to `done` / `failed` *and* recomputes the parent event's
|
|
20
|
+
* terminal state in the same transaction. That keeps the event
|
|
21
|
+
* terminal logic invariant-free — no counter to corrupt — at the cost
|
|
22
|
+
* of one extra query per terminal write.
|
|
23
|
+
*/
|
|
24
|
+
export class AgentRunBus {
|
|
25
|
+
connection;
|
|
26
|
+
log;
|
|
27
|
+
constructor(connection, log) {
|
|
28
|
+
this.connection = connection;
|
|
29
|
+
this.log = log;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Apply the events + agentruns schema (idempotent). The same SQL
|
|
33
|
+
* bundle is consumed by {@link EventBus.installSchema}, so calling
|
|
34
|
+
* either is sufficient on daemon start.
|
|
35
|
+
*/
|
|
36
|
+
async installSchema() {
|
|
37
|
+
await this.connection.getPool().query(SCHEMA_SQL);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Insert a new agentrun and return the persisted row.
|
|
41
|
+
*
|
|
42
|
+
* @throws If the underlying FK / check constraints reject the row
|
|
43
|
+
* (unknown `eventId`, malformed `topic`, invalid `calltype`).
|
|
44
|
+
*/
|
|
45
|
+
async add(run) {
|
|
46
|
+
const result = await this.connection.getPool().query(`INSERT INTO agentruns
|
|
47
|
+
(event_id, parent_agentrun_id, topic, handler, priority, state, prompt, payload, privileged, calltype)
|
|
48
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9, $10)
|
|
49
|
+
RETURNING *`, [
|
|
50
|
+
run.eventId,
|
|
51
|
+
run.parentAgentrunId ?? null,
|
|
52
|
+
run.topic,
|
|
53
|
+
run.handler,
|
|
54
|
+
run.priority ?? 50,
|
|
55
|
+
run.state ?? "pending",
|
|
56
|
+
run.prompt ?? null,
|
|
57
|
+
JSON.stringify(run.payload ?? {}),
|
|
58
|
+
run.privileged ?? false,
|
|
59
|
+
run.calltype ?? null,
|
|
60
|
+
]);
|
|
61
|
+
return mapRow(result.rows[0]);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Patch one or more fields on an existing agentrun by id. Always
|
|
65
|
+
* bumps `updated_at`. **Do not** use this to write a terminal state
|
|
66
|
+
* — use {@link settle} instead so the parent event's terminal state
|
|
67
|
+
* is recomputed in the same transaction.
|
|
68
|
+
*/
|
|
69
|
+
async update(id, patch) {
|
|
70
|
+
const sets = ["updated_at = now()"];
|
|
71
|
+
const values = [];
|
|
72
|
+
let n = 1;
|
|
73
|
+
if (patch.state !== undefined) {
|
|
74
|
+
sets.push(`state = $${n++}`);
|
|
75
|
+
values.push(patch.state);
|
|
76
|
+
}
|
|
77
|
+
if (patch.payload !== undefined) {
|
|
78
|
+
sets.push(`payload = $${n++}::jsonb`);
|
|
79
|
+
values.push(JSON.stringify(patch.payload));
|
|
80
|
+
}
|
|
81
|
+
if (patch.result !== undefined) {
|
|
82
|
+
sets.push(`result = $${n++}::jsonb`);
|
|
83
|
+
values.push(JSON.stringify(patch.result));
|
|
84
|
+
}
|
|
85
|
+
if (patch.resultText !== undefined) {
|
|
86
|
+
sets.push(`result_text = $${n++}`);
|
|
87
|
+
values.push(patch.resultText);
|
|
88
|
+
}
|
|
89
|
+
if (patch.error !== undefined) {
|
|
90
|
+
sets.push(`error = $${n++}`);
|
|
91
|
+
values.push(patch.error);
|
|
92
|
+
}
|
|
93
|
+
if (patch.priority !== undefined) {
|
|
94
|
+
sets.push(`priority = $${n++}`);
|
|
95
|
+
values.push(patch.priority);
|
|
96
|
+
}
|
|
97
|
+
if (patch.model !== undefined) {
|
|
98
|
+
sets.push(`model = $${n++}`);
|
|
99
|
+
values.push(patch.model);
|
|
100
|
+
}
|
|
101
|
+
if (patch.systemPrompt !== undefined) {
|
|
102
|
+
sets.push(`system_prompt = $${n++}`);
|
|
103
|
+
values.push(patch.systemPrompt);
|
|
104
|
+
}
|
|
105
|
+
if (patch.initialMessages !== undefined) {
|
|
106
|
+
sets.push(`initial_messages = $${n++}::jsonb`);
|
|
107
|
+
values.push(JSON.stringify(patch.initialMessages));
|
|
108
|
+
}
|
|
109
|
+
if (patch.calltype !== undefined) {
|
|
110
|
+
sets.push(`calltype = $${n++}`);
|
|
111
|
+
values.push(patch.calltype);
|
|
112
|
+
}
|
|
113
|
+
values.push(id);
|
|
114
|
+
const idParam = `$${n}`;
|
|
115
|
+
await this.connection
|
|
116
|
+
.getPool()
|
|
117
|
+
.query(`UPDATE agentruns SET ${sets.join(", ")} WHERE id = ${idParam}`, values);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Terminal write for an agentrun. Transitions the row to `done` or
|
|
121
|
+
* `failed`, optionally recording `result` / `resultText` / `error`,
|
|
122
|
+
* and recomputes the parent event's terminal state in the **same
|
|
123
|
+
* transaction**.
|
|
124
|
+
*
|
|
125
|
+
* The reactive event update is intentionally not a counter: it
|
|
126
|
+
* relies on the `agentruns(event_id)` index to check whether any
|
|
127
|
+
* sibling agentruns are still pending or running.
|
|
128
|
+
*/
|
|
129
|
+
async settle(id, toState, outcome = {}) {
|
|
130
|
+
const pool = this.connection.getPool();
|
|
131
|
+
const client = await pool.connect();
|
|
132
|
+
try {
|
|
133
|
+
await client.query("BEGIN");
|
|
134
|
+
const updated = await client.query(`UPDATE agentruns
|
|
135
|
+
SET state = $1,
|
|
136
|
+
result = COALESCE($2::jsonb, result),
|
|
137
|
+
result_text = COALESCE($3, result_text),
|
|
138
|
+
error = COALESCE($4, error),
|
|
139
|
+
updated_at = now()
|
|
140
|
+
WHERE id = $5
|
|
141
|
+
RETURNING event_id`, [
|
|
142
|
+
toState,
|
|
143
|
+
outcome.result === undefined ? null : JSON.stringify(outcome.result),
|
|
144
|
+
outcome.resultText ?? null,
|
|
145
|
+
outcome.error ?? null,
|
|
146
|
+
id,
|
|
147
|
+
]);
|
|
148
|
+
if (updated.rows.length === 0) {
|
|
149
|
+
await client.query("ROLLBACK");
|
|
150
|
+
throw new Error(`Agentrun ${id} not found`);
|
|
151
|
+
}
|
|
152
|
+
const eventId = updated.rows[0].event_id;
|
|
153
|
+
await client.query(EVENT_TERMINAL_UPDATE_SQL, [eventId, id, toState]);
|
|
154
|
+
await client.query("COMMIT");
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
await client.query("ROLLBACK").catch(() => { });
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
finally {
|
|
161
|
+
client.release();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fetch one agentrun by id, or `undefined` when missing.
|
|
166
|
+
*/
|
|
167
|
+
async getById(id) {
|
|
168
|
+
const result = await this.connection
|
|
169
|
+
.getPool()
|
|
170
|
+
.query(`SELECT * FROM agentruns WHERE id = $1`, [id]);
|
|
171
|
+
return result.rows.length > 0 ? mapRow(result.rows[0]) : undefined;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Fetch every agentrun in `state='pending'` whose `not_before` window
|
|
175
|
+
* has opened, in dispatch order (`priority desc, id asc`). The
|
|
176
|
+
* {@link AgentrunScheduler} calls this once per scheduling pass.
|
|
177
|
+
*
|
|
178
|
+
* Returns an empty array when nothing is ready. The Scheduler then
|
|
179
|
+
* waits on its NOTIFY subscription or a parked `not_before` timer
|
|
180
|
+
* before re-checking.
|
|
181
|
+
*/
|
|
182
|
+
async listEligible() {
|
|
183
|
+
const result = await this.connection.getPool().query(`SELECT * FROM agentruns
|
|
184
|
+
WHERE state = 'pending'
|
|
185
|
+
AND (not_before IS NULL OR not_before <= now())
|
|
186
|
+
ORDER BY priority DESC, id ASC`);
|
|
187
|
+
return result.rows.map(mapRow);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* `true` when every `calltype='started'` child of `parentId` is in
|
|
191
|
+
* a terminal state (`done` / `failed`). Used by the Scheduler
|
|
192
|
+
* after a started child settles, to decide whether the parent can
|
|
193
|
+
* leave `waiting` and go back to `pending`.
|
|
194
|
+
*
|
|
195
|
+
* Returns `true` when there are no started children at all (the
|
|
196
|
+
* trivially-vacuous case); the Scheduler still owns the "should
|
|
197
|
+
* we actually re-pend this parent?" decision and only invokes
|
|
198
|
+
* this method when at least one started child has just settled.
|
|
199
|
+
*/
|
|
200
|
+
async areAllStartedChildrenSettled(parentId) {
|
|
201
|
+
const result = await this.connection.getPool().query(`SELECT EXISTS (
|
|
202
|
+
SELECT 1 FROM agentruns
|
|
203
|
+
WHERE parent_agentrun_id = $1
|
|
204
|
+
AND calltype = 'started'
|
|
205
|
+
AND state NOT IN ('done','failed')
|
|
206
|
+
) AS exists`, [parentId]);
|
|
207
|
+
return result.rows[0]?.exists === false;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Fetch all agentrun rows whose `updated_at` is `>= since`, ordered
|
|
211
|
+
* by `(updated_at, id)`. Used by the polling-based report layer to
|
|
212
|
+
* pick up new agentruns and state transitions without NOTIFY.
|
|
213
|
+
*/
|
|
214
|
+
async listSince(since) {
|
|
215
|
+
const result = await this.connection.getPool().query(`SELECT * FROM agentruns
|
|
216
|
+
WHERE updated_at >= $1
|
|
217
|
+
ORDER BY updated_at, id`, [since]);
|
|
218
|
+
return result.rows.map(mapRow);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Fetch all agentruns belonging to one event, ordered by id.
|
|
222
|
+
* Used by the report layer to aggregate token totals and runtime
|
|
223
|
+
* across an event's full agentrun tree at finalization time.
|
|
224
|
+
*/
|
|
225
|
+
async listByEventId(eventId) {
|
|
226
|
+
const result = await this.connection.getPool().query(`SELECT * FROM agentruns
|
|
227
|
+
WHERE event_id = $1
|
|
228
|
+
ORDER BY id`, [eventId]);
|
|
229
|
+
return result.rows.map(mapRow);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Postpone an agentrun after a retryable inference error.
|
|
233
|
+
* Returns the row to `pending`, bumps `retry_count`, sets
|
|
234
|
+
* `not_before` to the supplied timestamp, and records the latest
|
|
235
|
+
* attempt's error text. The existing `agentruns_changed` UPDATE
|
|
236
|
+
* trigger fires on the state write so a NOTIFY-subscribed
|
|
237
|
+
* Scheduler wakes up — it just won't include the row in
|
|
238
|
+
* {@link listEligible} until `not_before` passes.
|
|
239
|
+
*
|
|
240
|
+
* Throws if the row is missing (mirrors {@link settle}).
|
|
241
|
+
*/
|
|
242
|
+
async postpone(id, runAfter, errorText) {
|
|
243
|
+
const result = await this.connection.getPool().query(`UPDATE agentruns
|
|
244
|
+
SET state = 'pending',
|
|
245
|
+
retry_count = retry_count + 1,
|
|
246
|
+
not_before = $2,
|
|
247
|
+
error = $3,
|
|
248
|
+
updated_at = now()
|
|
249
|
+
WHERE id = $1`, [id, runAfter, errorText]);
|
|
250
|
+
if (result.rowCount === 0) {
|
|
251
|
+
throw new Error(`Agentrun ${id} not found`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Subscribe to {@link AGENTRUNS_CHANNEL}. The notification payload
|
|
256
|
+
* (`<event_id>:<id>`) is parsed, the row is fetched by id, and
|
|
257
|
+
* `handler` is invoked with it. Fires on both INSERT and state
|
|
258
|
+
* UPDATE — callers that only care about one transition must filter
|
|
259
|
+
* on `row.state` themselves.
|
|
260
|
+
*
|
|
261
|
+
* Errors thrown by `handler` are caught and logged so one bad
|
|
262
|
+
* subscriber doesn't break others on the same channel.
|
|
263
|
+
*
|
|
264
|
+
* Returns a disposer; call it to unlisten. Idempotent.
|
|
265
|
+
*
|
|
266
|
+
* The {@link AgentrunScheduler} subscribes via
|
|
267
|
+
* {@link PostgresConnection.listen} directly (it only needs a
|
|
268
|
+
* "something changed" wake hint, not full row fetches); this
|
|
269
|
+
* helper exists for host-side consumers like
|
|
270
|
+
* `HostContext.events.emit`'s `onAgentRun` callback.
|
|
271
|
+
*/
|
|
272
|
+
async listen(handler) {
|
|
273
|
+
const wrapper = (payload) => {
|
|
274
|
+
this.log?.debug({ channel: AGENTRUNS_CHANNEL, payload }, "NOTIFY agentruns_changed");
|
|
275
|
+
void this.dispatchNotification(payload, handler);
|
|
276
|
+
};
|
|
277
|
+
await this.connection.listen(AGENTRUNS_CHANNEL, wrapper);
|
|
278
|
+
let disposed = false;
|
|
279
|
+
return async () => {
|
|
280
|
+
if (disposed) {
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
disposed = true;
|
|
284
|
+
await this.connection.unlisten(AGENTRUNS_CHANNEL, wrapper);
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Inner notification dispatcher for {@link listen}. Parses the
|
|
289
|
+
* channel payload (`<event_id>:<id>`), fetches the row by id, and
|
|
290
|
+
* invokes the handler — catching and logging any error from the
|
|
291
|
+
* handler itself.
|
|
292
|
+
*/
|
|
293
|
+
async dispatchNotification(payload, handler) {
|
|
294
|
+
// Payload format: `<event_id>:<agent_run_id>` (see Schema.ts
|
|
295
|
+
// `agentruns_notify_changed`). A malformed payload is a
|
|
296
|
+
// strong signal that the deployed trigger function is out of
|
|
297
|
+
// sync with the source — surface it loudly instead of
|
|
298
|
+
// silently dropping notifications and leaving the caller's
|
|
299
|
+
// spinner stuck forever.
|
|
300
|
+
const colon = payload.indexOf(":");
|
|
301
|
+
if (colon < 0) {
|
|
302
|
+
const warning = `AgentRunBus: malformed ${AGENTRUNS_CHANNEL} payload (no colon): "${payload}" — is the agentruns_notify_changed trigger function out of date? Restart the daemon to reinstall the schema.`;
|
|
303
|
+
if (this.log) {
|
|
304
|
+
this.log.warn({ payload }, warning);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
console.warn(warning);
|
|
308
|
+
}
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const id = payload.slice(colon + 1);
|
|
312
|
+
try {
|
|
313
|
+
const row = await this.getById(id);
|
|
314
|
+
if (!row) {
|
|
315
|
+
const warning = `AgentRunBus: no agentrun found for id="${id}" (payload="${payload}") — stale or malformed NOTIFY payload?`;
|
|
316
|
+
if (this.log) {
|
|
317
|
+
this.log.warn({ id, payload }, warning);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
console.warn(warning);
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
await handler(row);
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
this.log?.error({ id, err: err instanceof Error ? err.message : String(err) }, "AgentRunBus listen handler error");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Convert a snake_case raw row into the camelCase {@link AgentRunRow}.
|
|
333
|
+
* `state` is trusted to be a known {@link AgentRunState} (we control
|
|
334
|
+
* every writer).
|
|
335
|
+
*/
|
|
336
|
+
function mapRow(raw) {
|
|
337
|
+
return {
|
|
338
|
+
id: raw.id,
|
|
339
|
+
eventId: raw.event_id,
|
|
340
|
+
parentAgentrunId: raw.parent_agentrun_id,
|
|
341
|
+
topic: raw.topic,
|
|
342
|
+
handler: raw.handler,
|
|
343
|
+
priority: raw.priority,
|
|
344
|
+
state: raw.state,
|
|
345
|
+
prompt: raw.prompt,
|
|
346
|
+
payload: raw.payload,
|
|
347
|
+
result: raw.result,
|
|
348
|
+
resultText: raw.result_text,
|
|
349
|
+
error: raw.error,
|
|
350
|
+
privileged: raw.privileged,
|
|
351
|
+
calltype: raw.calltype === "scheduled" || raw.calltype === "started"
|
|
352
|
+
? raw.calltype
|
|
353
|
+
: null,
|
|
354
|
+
retryCount: raw.retry_count,
|
|
355
|
+
notBefore: raw.not_before,
|
|
356
|
+
model: raw.model,
|
|
357
|
+
systemPrompt: raw.system_prompt,
|
|
358
|
+
initialMessages: raw.initial_messages,
|
|
359
|
+
createdAt: raw.created_at,
|
|
360
|
+
updatedAt: raw.updated_at,
|
|
361
|
+
};
|
|
362
|
+
}
|