@dana4/sdk 0.1.0 → 0.5.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/README.md +5 -3
- package/dist/agent.d.ts +40 -4
- package/dist/agent.js +82 -18
- package/dist/ai.d.ts +4 -4
- package/dist/ai.js +170 -37
- package/dist/cli.js +11 -2
- package/dist/client.d.ts +54 -0
- package/dist/client.js +38 -10
- package/dist/cloudflare.js +10 -3
- package/dist/enroll.js +13 -4
- package/dist/run.js +7 -2
- package/dist/schema.d.ts +3733 -3503
- package/package.json +14 -3
package/dist/ai.js
CHANGED
|
@@ -18,10 +18,14 @@ export function formatDocumentList(documents) {
|
|
|
18
18
|
.map((dir) => {
|
|
19
19
|
const entries = groups
|
|
20
20
|
.get(dir)
|
|
21
|
-
|
|
21
|
+
?.sort((a, b) => Number(isFolder(b)) - Number(isFolder(a)) ||
|
|
22
|
+
leaf(a).localeCompare(leaf(b))) ?? [];
|
|
22
23
|
const names = entries.map((d) => leaf(d) + (isFolder(d) ? "/" : ""));
|
|
23
24
|
const width = Math.max(...names.map((n) => n.length));
|
|
24
|
-
return [
|
|
25
|
+
return [
|
|
26
|
+
`${dir}:`,
|
|
27
|
+
...entries.map((d, i) => ` ${names[i]?.padEnd(width)} ${d.title}`),
|
|
28
|
+
].join("\n");
|
|
25
29
|
})
|
|
26
30
|
.join("\n\n");
|
|
27
31
|
}
|
|
@@ -39,10 +43,13 @@ export function grep(content, pattern, context = 3) {
|
|
|
39
43
|
const shown = new Set(hits.flatMap((i) => Array.from({ length: 2 * context + 1 }, (_, k) => i - context + k)));
|
|
40
44
|
const out = [];
|
|
41
45
|
let prev = -2;
|
|
42
|
-
for (const i of [...shown]
|
|
46
|
+
for (const i of [...shown]
|
|
47
|
+
.filter((i) => i >= 0 && i < lines.length)
|
|
48
|
+
.sort((a, b) => a - b)) {
|
|
43
49
|
if (i !== prev + 1 && out.length)
|
|
44
50
|
out.push("---");
|
|
45
|
-
|
|
51
|
+
const line = lines[i] ?? "";
|
|
52
|
+
out.push(`${regex.test(line) ? ">" : " "} ${i + 1}: ${line}`);
|
|
46
53
|
prev = i;
|
|
47
54
|
}
|
|
48
55
|
return { matches: hits.length, lines: lines.length, text: out.join("\n") };
|
|
@@ -52,7 +59,7 @@ export function insertAt(document, line, content) {
|
|
|
52
59
|
const lines = document.match(/[^\n]*\n|[^\n]+$/g) ?? [];
|
|
53
60
|
const at = Math.max(0, Math.min(line - 1, lines.length));
|
|
54
61
|
// Appending after an unterminated last line: end it first, or the two join.
|
|
55
|
-
if (at === lines.length && at > 0 && !lines[at - 1]
|
|
62
|
+
if (at === lines.length && at > 0 && !lines[at - 1]?.endsWith("\n"))
|
|
56
63
|
lines[at - 1] += "\n";
|
|
57
64
|
lines.splice(at, 0, content.endsWith("\n") ? content : `${content}\n`);
|
|
58
65
|
return lines.join("");
|
|
@@ -67,11 +74,21 @@ export function capabilityToolSchema(schema) {
|
|
|
67
74
|
if (["workspace_id", "task_id"].includes(name))
|
|
68
75
|
return false;
|
|
69
76
|
const t = p?.type;
|
|
70
|
-
return typeof t === "string"
|
|
77
|
+
return typeof t === "string"
|
|
78
|
+
? PRIMITIVE.has(t)
|
|
79
|
+
: Array.isArray(t) &&
|
|
80
|
+
t.every((x) => typeof x === "string" && PRIMITIVE.has(x));
|
|
71
81
|
});
|
|
72
82
|
const kept = new Set(keep.map(([n]) => n));
|
|
73
|
-
const required = Array.isArray(schema?.required)
|
|
74
|
-
|
|
83
|
+
const required = Array.isArray(schema?.required)
|
|
84
|
+
? schema.required.filter((r) => typeof r === "string" && kept.has(r))
|
|
85
|
+
: [];
|
|
86
|
+
return {
|
|
87
|
+
type: "object",
|
|
88
|
+
additionalProperties: false,
|
|
89
|
+
properties: Object.fromEntries(keep),
|
|
90
|
+
required,
|
|
91
|
+
};
|
|
75
92
|
}
|
|
76
93
|
/** Tools for reading and writing the workspace's documents, messaging, and the
|
|
77
94
|
* thread's plan — plus, unless `delegation: false`, one `<agent>__<capability>`
|
|
@@ -80,9 +97,12 @@ export function capabilityToolSchema(schema) {
|
|
|
80
97
|
export async function dana4Tools(ctx, opts = {}) {
|
|
81
98
|
const tools = {
|
|
82
99
|
list_documents: tool({
|
|
83
|
-
description: "List documents in a folder with their paths and titles. Optionally recurse into subfolders.",
|
|
100
|
+
description: "List documents in a folder with their paths and titles. Optionally recurse into subfolders. To find documents about a topic, use search_documents instead: listing returns every document and costs far more tokens.",
|
|
84
101
|
inputSchema: z.object({
|
|
85
|
-
path: z
|
|
102
|
+
path: z
|
|
103
|
+
.string()
|
|
104
|
+
.default("/")
|
|
105
|
+
.describe("Folder to list, as a path (e.g. '/foo/bar'). Defaults to the root."),
|
|
86
106
|
recursive: z
|
|
87
107
|
.boolean()
|
|
88
108
|
.default(false)
|
|
@@ -94,19 +114,33 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
94
114
|
description: "Search for a text pattern within a document. Returns matching lines with line numbers and surrounding context. Use this BEFORE read_document to find relevant sections without reading the entire file.",
|
|
95
115
|
inputSchema: z.object({
|
|
96
116
|
path: z.string().describe("Path of the document to search in."),
|
|
97
|
-
pattern: z
|
|
98
|
-
|
|
117
|
+
pattern: z
|
|
118
|
+
.string()
|
|
119
|
+
.describe("Text or regex pattern to search for. Case-insensitive."),
|
|
120
|
+
context_lines: z
|
|
121
|
+
.number()
|
|
122
|
+
.int()
|
|
123
|
+
.default(3)
|
|
124
|
+
.describe("Number of lines to show before and after each match."),
|
|
99
125
|
}),
|
|
100
126
|
execute: async ({ path, pattern, context_lines }) => {
|
|
101
127
|
const r = grep((await ctx.docs.get(path)).content, pattern, context_lines);
|
|
102
|
-
return r.matches
|
|
128
|
+
return r.matches
|
|
129
|
+
? `Found ${r.matches} match(es) in ${path} (${r.lines} lines total):\n${r.text}`
|
|
130
|
+
: `No matches for '${pattern}' in ${path}`;
|
|
103
131
|
},
|
|
104
132
|
}),
|
|
105
133
|
search_documents: tool({
|
|
106
134
|
description: "Search across ALL documents in the workspace by meaning or keyword, returning the most relevant documents with a snippet and relevance score. Use this when you don't know which document holds the content you need. Use grep_document instead to search within a single known document.",
|
|
107
135
|
inputSchema: z.object({
|
|
108
|
-
query: z
|
|
109
|
-
|
|
136
|
+
query: z
|
|
137
|
+
.string()
|
|
138
|
+
.describe("Natural-language or keyword query to search across all documents in the workspace."),
|
|
139
|
+
limit: z
|
|
140
|
+
.number()
|
|
141
|
+
.int()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("Max number of results to return. Defaults to the server default."),
|
|
110
144
|
}),
|
|
111
145
|
execute: async ({ query, limit }) => {
|
|
112
146
|
const results = await ctx.docs.search(query, limit);
|
|
@@ -114,7 +148,10 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
114
148
|
return `No documents matched '${query}'.`;
|
|
115
149
|
return [
|
|
116
150
|
`Found ${results.length} result(s) for '${query}':\n`,
|
|
117
|
-
...results.flatMap((r) => [
|
|
151
|
+
...results.flatMap((r) => [
|
|
152
|
+
`- ${r.path} — ${r.title} (score: ${r.score.toFixed(3)})`,
|
|
153
|
+
...(r.snippet ? [` ${r.snippet}`] : []),
|
|
154
|
+
]),
|
|
118
155
|
].join("\n");
|
|
119
156
|
},
|
|
120
157
|
}),
|
|
@@ -122,7 +159,11 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
122
159
|
description: `Read a document's content with line numbers. Returns up to ${MAX_LINES_PER_READ} lines.\n\nUsage:\n- Use grep_document first to find relevant line numbers, then read targeted ranges.\n- Use offset and limit to read specific sections. Avoid reading entire large documents.\n- Lines are prefixed with line numbers: \`42: content here\`.\n- Call this tool in parallel when reading multiple documents.`,
|
|
123
160
|
inputSchema: z.object({
|
|
124
161
|
path: z.string().describe("The path to the document to read."),
|
|
125
|
-
offset: z
|
|
162
|
+
offset: z
|
|
163
|
+
.number()
|
|
164
|
+
.int()
|
|
165
|
+
.optional()
|
|
166
|
+
.describe("Line number to start reading from (1-indexed). Defaults to 1."),
|
|
126
167
|
limit: z
|
|
127
168
|
.number()
|
|
128
169
|
.int()
|
|
@@ -138,18 +179,24 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
138
179
|
.slice(start, end)
|
|
139
180
|
.map((l, i) => `${start + i + 1}: ${l}`)
|
|
140
181
|
.join("\n");
|
|
141
|
-
const more = end < lines.length
|
|
182
|
+
const more = end < lines.length
|
|
183
|
+
? `\n\n[Showing lines ${start + 1}-${end} of ${lines.length}. Use offset=${end + 1} to read more.]`
|
|
184
|
+
: "";
|
|
142
185
|
return `Title: ${doc.title}\nPath: ${path}\nTotal lines: ${lines.length}\nContent:\n\n${body}${more}\n`;
|
|
143
186
|
},
|
|
144
187
|
}),
|
|
145
188
|
get_step_result: tool({
|
|
146
189
|
description: "Fetch the result produced by an earlier step in the current journey, by its step id. Returns the result as JSON, or a note if the step has not produced a result yet.",
|
|
147
190
|
inputSchema: z.object({
|
|
148
|
-
step_id: z
|
|
191
|
+
step_id: z
|
|
192
|
+
.string()
|
|
193
|
+
.describe("The id of the step whose result to fetch (e.g. 'step_brand_questions')."),
|
|
149
194
|
}),
|
|
150
195
|
execute: async ({ step_id }) => {
|
|
151
196
|
const result = await ctx.stepResult(step_id);
|
|
152
|
-
return result == null
|
|
197
|
+
return result == null
|
|
198
|
+
? `No result available for step '${step_id}' yet (it may not have run or completed).`
|
|
199
|
+
: JSON.stringify(result, null, 2);
|
|
153
200
|
},
|
|
154
201
|
}),
|
|
155
202
|
create_document: tool({
|
|
@@ -173,7 +220,10 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
173
220
|
description: `Overwrite a document's entire content. Max ~${MAX_LINES_PER_WRITE} lines.\n\nONLY use for small documents. For anything larger, use create_document + append_document.\nFor targeted changes, prefer edit_document or insert_in_document instead.`,
|
|
174
221
|
inputSchema: z.object({
|
|
175
222
|
path: z.string().describe("Path to the document to overwrite."),
|
|
176
|
-
content: z
|
|
223
|
+
content: z
|
|
224
|
+
.string()
|
|
225
|
+
.default("")
|
|
226
|
+
.describe("Full replacement content. Must be under ~200 lines."),
|
|
177
227
|
}),
|
|
178
228
|
execute: async ({ path, content }) => {
|
|
179
229
|
if (!content)
|
|
@@ -189,7 +239,9 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
189
239
|
description: "Append content to the end of an existing document.\n\nUse this for building large documents incrementally:\n1. create_document with opening structure\n2. append_document for each section\nKeep each append under ~300 lines.",
|
|
190
240
|
inputSchema: z.object({
|
|
191
241
|
path: z.string().describe("Path of the document to append to."),
|
|
192
|
-
content: z
|
|
242
|
+
content: z
|
|
243
|
+
.string()
|
|
244
|
+
.describe("Content to append to the end of the document."),
|
|
193
245
|
}),
|
|
194
246
|
execute: async ({ path, content }) => {
|
|
195
247
|
await ctx.docs.append(path, content);
|
|
@@ -200,9 +252,16 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
200
252
|
description: "Find and replace exact text in a document.\n\nUsage:\n- You MUST read_document or grep_document first to see the exact text.\n- old_str must match exactly (whitespace, indentation, line breaks).\n- old_str must be unique in the document. Include surrounding lines if needed, or set replace_all to change every occurrence.\n- Do NOT include line number prefixes (e.g. `42: `) in old_str/new_str.",
|
|
201
253
|
inputSchema: z.object({
|
|
202
254
|
path: z.string().describe("Path to the document to modify."),
|
|
203
|
-
old_str: z
|
|
204
|
-
|
|
205
|
-
|
|
255
|
+
old_str: z
|
|
256
|
+
.string()
|
|
257
|
+
.describe("Exact text to find and replace. Must match uniquely. Include surrounding lines for context if needed."),
|
|
258
|
+
new_str: z
|
|
259
|
+
.string()
|
|
260
|
+
.describe("Replacement text. Must differ from old_str."),
|
|
261
|
+
replace_all: z
|
|
262
|
+
.boolean()
|
|
263
|
+
.default(false)
|
|
264
|
+
.describe("Replace every occurrence instead of requiring a unique match."),
|
|
206
265
|
}),
|
|
207
266
|
execute: async ({ path, old_str, new_str, replace_all }) => {
|
|
208
267
|
try {
|
|
@@ -222,15 +281,47 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
222
281
|
.number()
|
|
223
282
|
.int()
|
|
224
283
|
.describe("Line number to insert BEFORE (1-indexed). Use 0 to insert at the very beginning. Use a line number beyond the end to append."),
|
|
225
|
-
content: z
|
|
284
|
+
content: z
|
|
285
|
+
.string()
|
|
286
|
+
.describe("Content to insert at the specified line."),
|
|
226
287
|
}),
|
|
227
288
|
execute: async ({ path, line, content }) => {
|
|
228
289
|
const doc = await ctx.docs.get(path, "editing");
|
|
229
290
|
await ctx.docs.replace(path, insertAt(doc.content, line, content));
|
|
230
|
-
const n = (content.endsWith("\n") ? content : `${content}\n`).split("\n")
|
|
291
|
+
const n = (content.endsWith("\n") ? content : `${content}\n`).split("\n")
|
|
292
|
+
.length - 1;
|
|
231
293
|
return `Inserted ${n} line(s) at line ${line} in ${path}`;
|
|
232
294
|
},
|
|
233
295
|
}),
|
|
296
|
+
create_ticket: tool({
|
|
297
|
+
description: "Create a ticket on the workspace's board. Tickets are identified by their number (#42), unique within the workspace; blocked_by takes those numbers.",
|
|
298
|
+
inputSchema: z.object({
|
|
299
|
+
title: z.string().describe("The ticket's title."),
|
|
300
|
+
description: z
|
|
301
|
+
.string()
|
|
302
|
+
.optional()
|
|
303
|
+
.describe("What needs doing, in markdown."),
|
|
304
|
+
status: z
|
|
305
|
+
.enum([
|
|
306
|
+
"backlog",
|
|
307
|
+
"todo",
|
|
308
|
+
"in_progress",
|
|
309
|
+
"in_review",
|
|
310
|
+
"done",
|
|
311
|
+
"canceled",
|
|
312
|
+
])
|
|
313
|
+
.optional()
|
|
314
|
+
.describe("The board column. Defaults to backlog."),
|
|
315
|
+
blocked_by: z
|
|
316
|
+
.array(z.number().int())
|
|
317
|
+
.default([])
|
|
318
|
+
.describe("Numbers of the tickets that must finish first."),
|
|
319
|
+
}),
|
|
320
|
+
execute: async (ticket) => {
|
|
321
|
+
const t = await ctx.tickets.create(ticket);
|
|
322
|
+
return `Ticket #${t.number} created in workspace ${ctx.workspaceId}`;
|
|
323
|
+
},
|
|
324
|
+
}),
|
|
234
325
|
send_message: tool({
|
|
235
326
|
description: "Send a message to a channel. Uses the current channel if channel_id is omitted.",
|
|
236
327
|
inputSchema: z.object({
|
|
@@ -248,20 +339,42 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
248
339
|
plan: z
|
|
249
340
|
.string()
|
|
250
341
|
.describe("The full plan as a markdown checklist, e.g. `- [x] research\n- [ ] draft`. This REPLACES the existing plan, so include every item, not just the changed ones. Use this to author the initial plan; prefer complete_plan_item / add_plan_item for incremental edits."),
|
|
251
|
-
channel_id: z
|
|
342
|
+
channel_id: z
|
|
343
|
+
.string()
|
|
344
|
+
.optional()
|
|
345
|
+
.describe("The id of the channel. Defaults to the current channel."),
|
|
252
346
|
}),
|
|
253
347
|
execute: async ({ plan, channel_id }) => {
|
|
254
348
|
const ch = await ctx.plan.set(plan, channel_id ?? ctx.channelId);
|
|
255
349
|
return planStatus(ch.id, ch.plan_completed);
|
|
256
350
|
},
|
|
257
351
|
}),
|
|
352
|
+
set_memory: tool({
|
|
353
|
+
description: "Overwrite this message thread's memory: markdown notes shared by its agents and people.\n\nUse it to log what happened, what worked, what failed and what to remember next run. The current memory is in your instructions; send the whole updated text, not just the new notes.",
|
|
354
|
+
inputSchema: z.object({
|
|
355
|
+
memory: z
|
|
356
|
+
.string()
|
|
357
|
+
.describe("The full memory as markdown. This REPLACES the existing memory, so start from the current one in your instructions and edit it: keep what is still useful, add what happened, what worked, what failed and what to remember next run, and drop what is stale."),
|
|
358
|
+
channel_id: z
|
|
359
|
+
.string()
|
|
360
|
+
.optional()
|
|
361
|
+
.describe("The id of the channel. Defaults to the current channel."),
|
|
362
|
+
}),
|
|
363
|
+
execute: async ({ memory, channel_id }) => {
|
|
364
|
+
const ch = await ctx.memory.set(memory, channel_id ?? ctx.channelId);
|
|
365
|
+
return `Memory updated for channel ${ch.id}.`;
|
|
366
|
+
},
|
|
367
|
+
}),
|
|
258
368
|
complete_plan_item: tool({
|
|
259
369
|
description: "Check off one item in this message thread's plan as you finish it.\n\nUsage:\n- The current plan (a markdown checklist) is in your instructions.\n- Pass the item's exact label text — just that one item, not the whole plan.\n- If the text matches no item or several, you'll get an error; retry with more of the item's wording.\n- The thread is complete once every item is checked.",
|
|
260
370
|
inputSchema: z.object({
|
|
261
371
|
item: z
|
|
262
372
|
.string()
|
|
263
373
|
.describe("The exact label text of the checklist item to check off (the words after the `[ ]`), as shown in the current plan in your instructions. Matched ignoring case and extra spaces; it must be unambiguous."),
|
|
264
|
-
channel_id: z
|
|
374
|
+
channel_id: z
|
|
375
|
+
.string()
|
|
376
|
+
.optional()
|
|
377
|
+
.describe("The id of the channel. Defaults to the current channel."),
|
|
265
378
|
}),
|
|
266
379
|
execute: async ({ item, channel_id }) => {
|
|
267
380
|
try {
|
|
@@ -276,8 +389,13 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
276
389
|
add_plan_item: tool({
|
|
277
390
|
description: "Append a new unchecked item to this message thread's plan.\n\nUse this to record a step you've discovered; pass just the new item's text, not the whole plan.",
|
|
278
391
|
inputSchema: z.object({
|
|
279
|
-
item: z
|
|
280
|
-
|
|
392
|
+
item: z
|
|
393
|
+
.string()
|
|
394
|
+
.describe("The text of the new unchecked checklist item to append."),
|
|
395
|
+
channel_id: z
|
|
396
|
+
.string()
|
|
397
|
+
.optional()
|
|
398
|
+
.describe("The id of the channel. Defaults to the current channel."),
|
|
281
399
|
}),
|
|
282
400
|
execute: async ({ item, channel_id }) => {
|
|
283
401
|
const ch = await ctx.plan.add(item, channel_id ?? ctx.channelId);
|
|
@@ -290,7 +408,9 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
290
408
|
if (opts.delegation === false)
|
|
291
409
|
return tools;
|
|
292
410
|
// Without the lookup the chat still has every other tool, so don't fail it.
|
|
293
|
-
const agents = await ctx.client.workspaces
|
|
411
|
+
const agents = await ctx.client.workspaces
|
|
412
|
+
.agents(ctx.workspaceId)
|
|
413
|
+
.catch((e) => {
|
|
294
414
|
console.warn("dana4: listing agents failed; no delegation tools:", e instanceof Error ? e.message : e);
|
|
295
415
|
return [];
|
|
296
416
|
});
|
|
@@ -302,7 +422,8 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
302
422
|
for (let i = 2; name in tools; i++)
|
|
303
423
|
name = `${base.slice(0, 63 - String(i).length)}_${i}`;
|
|
304
424
|
tools[name] = tool({
|
|
305
|
-
description: cap.description ||
|
|
425
|
+
description: cap.description ||
|
|
426
|
+
`Trigger \`${cap.key}\` from agent \`${agent.username}\`.`,
|
|
306
427
|
inputSchema: jsonSchema(capabilityToolSchema(cap.input_schema)),
|
|
307
428
|
execute: async (inputs) => {
|
|
308
429
|
const taskId = await ctx.delegate(agent.username, cap.key, inputs);
|
|
@@ -318,20 +439,32 @@ export async function dana4Tools(ctx, opts = {}) {
|
|
|
318
439
|
* the author. Only conversational messages (and errors) are kept. */
|
|
319
440
|
export function chatHistory(messages, { me, exclude }) {
|
|
320
441
|
return messages
|
|
321
|
-
.filter((m) => (m.category === "default" || m.category === "error") &&
|
|
442
|
+
.filter((m) => (m.category === "default" || m.category === "error") &&
|
|
443
|
+
m.id !== exclude)
|
|
322
444
|
.sort((a, b) => a.time.created_at.localeCompare(b.time.created_at))
|
|
323
445
|
.map((m) => {
|
|
324
446
|
const content = `${m.from_username}: ${m.category === "error" ? "ERROR: " : ""}${m.message}`;
|
|
325
|
-
return m.from_username === me
|
|
447
|
+
return m.from_username === me
|
|
448
|
+
? { role: "assistant", content }
|
|
449
|
+
: { role: "user", content };
|
|
326
450
|
});
|
|
327
451
|
}
|
|
328
|
-
/** `base` followed by the thread's topics, intent and
|
|
329
|
-
* what the conversation is for. */
|
|
452
|
+
/** `base` followed by the thread's topics, the board, intent, plan and memory, so the
|
|
453
|
+
* model knows what the conversation is for. */
|
|
330
454
|
export function threadInstructions(base, thread) {
|
|
455
|
+
const tickets = thread.tickets ?? [];
|
|
331
456
|
const context = [
|
|
332
457
|
...thread.topics.map((t) => `Thread topic: ${t.title} — ${t.summary}`),
|
|
458
|
+
...(tickets.length
|
|
459
|
+
? [
|
|
460
|
+
`Board:\n${tickets
|
|
461
|
+
.map((t) => `- ${t.number != null ? `#${t.number} ` : ""}${t.title} [${t.board_status}]${t.assignee ? ` @${t.assignee}` : ""}`)
|
|
462
|
+
.join("\n")}`,
|
|
463
|
+
]
|
|
464
|
+
: []),
|
|
333
465
|
...(thread.intent ? [`Thread intent: ${thread.intent}`] : []),
|
|
334
466
|
...(thread.plan ? [`Thread plan:\n${thread.plan}`] : []),
|
|
467
|
+
...(thread.memory ? [`Thread memory:\n${thread.memory}`] : []),
|
|
335
468
|
].join("\n");
|
|
336
469
|
return [base, context].filter(Boolean).join("\n\n");
|
|
337
470
|
}
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,12 @@ import { parseArgs } from "node:util";
|
|
|
3
3
|
import { enroll } from "./enroll.js";
|
|
4
4
|
const { values, positionals } = parseArgs({
|
|
5
5
|
allowPositionals: true,
|
|
6
|
-
options: {
|
|
6
|
+
options: {
|
|
7
|
+
username: { type: "string" },
|
|
8
|
+
bio: { type: "string" },
|
|
9
|
+
description: { type: "string" },
|
|
10
|
+
url: { type: "string" },
|
|
11
|
+
},
|
|
7
12
|
});
|
|
8
13
|
const username = values.username;
|
|
9
14
|
if (positionals[0] !== "enroll" || !username) {
|
|
@@ -11,6 +16,10 @@ if (positionals[0] !== "enroll" || !username) {
|
|
|
11
16
|
process.exitCode = 2;
|
|
12
17
|
}
|
|
13
18
|
else {
|
|
14
|
-
const key = await enroll({
|
|
19
|
+
const key = await enroll({
|
|
20
|
+
...values,
|
|
21
|
+
username,
|
|
22
|
+
url: values.url ?? process.env.DANA4_URL,
|
|
23
|
+
});
|
|
15
24
|
console.log(`\nApproved. Your API key (shown once), e.g. for DANA4_API_KEY:\n\n${key}`);
|
|
16
25
|
}
|
package/dist/client.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export type Automation = S["Automation"];
|
|
|
6
6
|
export type Channel = S["Channel"];
|
|
7
7
|
export type ChatThread = S["ChatThread"];
|
|
8
8
|
export type CreateAutomationBody = S["CreateAutomationBody"];
|
|
9
|
+
export type CreateTicketBody = S["CreateTicketBody"];
|
|
9
10
|
export type CreateWorkflowPayload = S["CreateWorkflowPayload"];
|
|
10
11
|
export type Document = S["Document"];
|
|
11
12
|
export type DocumentHeader = S["DocumentHeader"];
|
|
@@ -16,6 +17,7 @@ export type MessageCategory = S["MessageCategory"];
|
|
|
16
17
|
export type Pipe = S["Pipe"];
|
|
17
18
|
export type PresenceActivity = S["PresenceActivity"];
|
|
18
19
|
export type SearchResult = S["SearchResult"];
|
|
20
|
+
export type SdkTicket = S["SdkTicket"];
|
|
19
21
|
export type Task = S["Task"];
|
|
20
22
|
export type TaskStatus = S["TaskStatus"];
|
|
21
23
|
/** `cost_details` is optional on the wire; utoipa marks it required. */
|
|
@@ -95,6 +97,7 @@ export declare class Dana4Client {
|
|
|
95
97
|
execution_duration?: number | null;
|
|
96
98
|
id: string;
|
|
97
99
|
journey_id: string;
|
|
100
|
+
number?: number | null;
|
|
98
101
|
order: number;
|
|
99
102
|
params?: {
|
|
100
103
|
[key: string]: unknown;
|
|
@@ -106,6 +109,9 @@ export declare class Dana4Client {
|
|
|
106
109
|
step_id: string;
|
|
107
110
|
step_type: components["schemas"]["JourneyStepType"];
|
|
108
111
|
time: components["schemas"]["Timestamps"];
|
|
112
|
+
tool_calls?: {
|
|
113
|
+
[key: string]: unknown;
|
|
114
|
+
}[];
|
|
109
115
|
}[]>;
|
|
110
116
|
assigned: () => Promise<{
|
|
111
117
|
channel_id: string;
|
|
@@ -116,6 +122,7 @@ export declare class Dana4Client {
|
|
|
116
122
|
execution_duration?: number | null;
|
|
117
123
|
id: string;
|
|
118
124
|
journey_id: string;
|
|
125
|
+
number?: number | null;
|
|
119
126
|
order: number;
|
|
120
127
|
params?: {
|
|
121
128
|
[key: string]: unknown;
|
|
@@ -127,6 +134,9 @@ export declare class Dana4Client {
|
|
|
127
134
|
step_id: string;
|
|
128
135
|
step_type: components["schemas"]["JourneyStepType"];
|
|
129
136
|
time: components["schemas"]["Timestamps"];
|
|
137
|
+
tool_calls?: {
|
|
138
|
+
[key: string]: unknown;
|
|
139
|
+
}[];
|
|
130
140
|
}[]>;
|
|
131
141
|
unassigned: () => Promise<{
|
|
132
142
|
channel_id: string;
|
|
@@ -137,6 +147,7 @@ export declare class Dana4Client {
|
|
|
137
147
|
execution_duration?: number | null;
|
|
138
148
|
id: string;
|
|
139
149
|
journey_id: string;
|
|
150
|
+
number?: number | null;
|
|
140
151
|
order: number;
|
|
141
152
|
params?: {
|
|
142
153
|
[key: string]: unknown;
|
|
@@ -148,6 +159,9 @@ export declare class Dana4Client {
|
|
|
148
159
|
step_id: string;
|
|
149
160
|
step_type: components["schemas"]["JourneyStepType"];
|
|
150
161
|
time: components["schemas"]["Timestamps"];
|
|
162
|
+
tool_calls?: {
|
|
163
|
+
[key: string]: unknown;
|
|
164
|
+
}[];
|
|
151
165
|
}[]>;
|
|
152
166
|
claim: (taskId: string, capability: string) => Promise<{
|
|
153
167
|
channel_id: string;
|
|
@@ -158,6 +172,7 @@ export declare class Dana4Client {
|
|
|
158
172
|
execution_duration?: number | null;
|
|
159
173
|
id: string;
|
|
160
174
|
journey_id: string;
|
|
175
|
+
number?: number | null;
|
|
161
176
|
order: number;
|
|
162
177
|
params?: {
|
|
163
178
|
[key: string]: unknown;
|
|
@@ -169,6 +184,9 @@ export declare class Dana4Client {
|
|
|
169
184
|
step_id: string;
|
|
170
185
|
step_type: components["schemas"]["JourneyStepType"];
|
|
171
186
|
time: components["schemas"]["Timestamps"];
|
|
187
|
+
tool_calls?: {
|
|
188
|
+
[key: string]: unknown;
|
|
189
|
+
}[];
|
|
172
190
|
}>;
|
|
173
191
|
/** Start a one-step journey (e.g. `read_message`); answers its task id. */
|
|
174
192
|
start: (body: {
|
|
@@ -289,9 +307,11 @@ export declare class Dana4Client {
|
|
|
289
307
|
direct?: boolean;
|
|
290
308
|
document_id?: string | null;
|
|
291
309
|
intent?: string | null;
|
|
310
|
+
memory?: string | null;
|
|
292
311
|
messages: components["schemas"]["Message"][];
|
|
293
312
|
parent_channel_id?: string | null;
|
|
294
313
|
plan?: string | null;
|
|
314
|
+
tickets?: components["schemas"]["TicketSummary"][];
|
|
295
315
|
topics: components["schemas"]["TopicSummary"][];
|
|
296
316
|
}[]>;
|
|
297
317
|
create: (body: S["CreateDocumentPayload"]) => Promise<string>;
|
|
@@ -311,9 +331,11 @@ export declare class Dana4Client {
|
|
|
311
331
|
direct?: boolean;
|
|
312
332
|
document_id?: string | null;
|
|
313
333
|
intent?: string | null;
|
|
334
|
+
memory?: string | null;
|
|
314
335
|
messages: components["schemas"]["Message"][];
|
|
315
336
|
parent_channel_id?: string | null;
|
|
316
337
|
plan?: string | null;
|
|
338
|
+
tickets?: components["schemas"]["TicketSummary"][];
|
|
317
339
|
topics: components["schemas"]["TopicSummary"][];
|
|
318
340
|
}>;
|
|
319
341
|
messages: (channelId: string, range?: {
|
|
@@ -324,9 +346,11 @@ export declare class Dana4Client {
|
|
|
324
346
|
direct?: boolean;
|
|
325
347
|
document_id?: string | null;
|
|
326
348
|
intent?: string | null;
|
|
349
|
+
memory?: string | null;
|
|
327
350
|
messages: components["schemas"]["Message"][];
|
|
328
351
|
parent_channel_id?: string | null;
|
|
329
352
|
plan?: string | null;
|
|
353
|
+
tickets?: components["schemas"]["TicketSummary"][];
|
|
330
354
|
topics: components["schemas"]["TopicSummary"][];
|
|
331
355
|
}>;
|
|
332
356
|
send: (body: S["SendMessagePayload"]) => Promise<{
|
|
@@ -343,6 +367,7 @@ export declare class Dana4Client {
|
|
|
343
367
|
document_id: string;
|
|
344
368
|
id: string;
|
|
345
369
|
intent?: string | null;
|
|
370
|
+
memory?: string | null;
|
|
346
371
|
owners: string[];
|
|
347
372
|
parent_channel_id?: string | null;
|
|
348
373
|
parent_message_id?: string | null;
|
|
@@ -357,6 +382,22 @@ export declare class Dana4Client {
|
|
|
357
382
|
document_id: string;
|
|
358
383
|
id: string;
|
|
359
384
|
intent?: string | null;
|
|
385
|
+
memory?: string | null;
|
|
386
|
+
owners: string[];
|
|
387
|
+
parent_channel_id?: string | null;
|
|
388
|
+
parent_message_id?: string | null;
|
|
389
|
+
plan?: string | null;
|
|
390
|
+
plan_completed: boolean;
|
|
391
|
+
private: boolean;
|
|
392
|
+
time: components["schemas"]["Timestamps"];
|
|
393
|
+
title: string;
|
|
394
|
+
workspace_id: string;
|
|
395
|
+
}>;
|
|
396
|
+
setMemory: (channelId: string, memory: string) => Promise<{
|
|
397
|
+
document_id: string;
|
|
398
|
+
id: string;
|
|
399
|
+
intent?: string | null;
|
|
400
|
+
memory?: string | null;
|
|
360
401
|
owners: string[];
|
|
361
402
|
parent_channel_id?: string | null;
|
|
362
403
|
parent_message_id?: string | null;
|
|
@@ -371,6 +412,7 @@ export declare class Dana4Client {
|
|
|
371
412
|
document_id: string;
|
|
372
413
|
id: string;
|
|
373
414
|
intent?: string | null;
|
|
415
|
+
memory?: string | null;
|
|
374
416
|
owners: string[];
|
|
375
417
|
parent_channel_id?: string | null;
|
|
376
418
|
parent_message_id?: string | null;
|
|
@@ -385,6 +427,7 @@ export declare class Dana4Client {
|
|
|
385
427
|
document_id: string;
|
|
386
428
|
id: string;
|
|
387
429
|
intent?: string | null;
|
|
430
|
+
memory?: string | null;
|
|
388
431
|
owners: string[];
|
|
389
432
|
parent_channel_id?: string | null;
|
|
390
433
|
parent_message_id?: string | null;
|
|
@@ -469,6 +512,17 @@ export declare class Dana4Client {
|
|
|
469
512
|
}>;
|
|
470
513
|
delete: (automationId: string) => Promise<string>;
|
|
471
514
|
};
|
|
515
|
+
readonly tickets: {
|
|
516
|
+
/** Put a ticket on the workspace's board. Tickets are referred to by their
|
|
517
|
+
* per-workspace number (`blocked_by: [12]` means #12). */
|
|
518
|
+
create: (body: CreateTicketBody) => Promise<{
|
|
519
|
+
blocked_by: number[];
|
|
520
|
+
number: number;
|
|
521
|
+
status: components["schemas"]["BoardStatus"];
|
|
522
|
+
title: string;
|
|
523
|
+
workspace_id: string;
|
|
524
|
+
}>;
|
|
525
|
+
};
|
|
472
526
|
readonly workflows: {
|
|
473
527
|
create: (body: CreateWorkflowPayload) => Promise<{
|
|
474
528
|
definition: string;
|