@spendgraph/tools 0.6.0 → 0.7.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 +3 -2
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.js +1 -0
- package/dist/{builtin/write-document/write-document.d.ts → agents/moa/index.d.ts} +7 -2
- package/dist/agents/moa/index.js +1 -0
- package/dist/{builtin/write-document/commission.d.ts → agents/moa/moa.d.ts} +15 -15
- package/dist/agents/moa/moa.js +13 -0
- package/dist/{builtin/write-document → agents/moa}/types.d.ts +9 -9
- package/dist/builtin/calculate/calculate.d.ts +2 -0
- package/dist/builtin/calculate/calculate.js +1 -1
- package/dist/builtin/calculate/index.d.ts +2 -1
- package/dist/builtin/calculate/index.js +1 -1
- package/dist/builtin/code-exec/code-exec.d.ts +14 -0
- package/dist/builtin/date/date.d.ts +1 -1
- package/dist/builtin/date/date.js +1 -1
- package/dist/builtin/date/index.d.ts +1 -0
- package/dist/builtin/date/index.js +1 -1
- package/dist/builtin/date/shift.d.ts +1 -1
- package/dist/builtin/date/shift.js +1 -1
- package/dist/builtin/date/words.d.ts +13 -0
- package/dist/builtin/date/words.js +1 -0
- package/dist/builtin/decline/decline.d.ts +49 -0
- package/dist/builtin/decline/decline.js +1 -0
- package/dist/builtin/decline/index.d.ts +1 -0
- package/dist/builtin/decline/index.js +1 -0
- package/dist/builtin/escalate/escalate.d.ts +19 -0
- package/dist/builtin/escalate/escalate.js +1 -1
- package/dist/builtin/escalate/index.d.ts +1 -1
- package/dist/builtin/escalate/index.js +1 -1
- package/dist/builtin/extract/extract.d.ts +25 -0
- package/dist/builtin/extract/extract.js +1 -0
- package/dist/builtin/extract/index.d.ts +3 -0
- package/dist/builtin/extract/index.js +1 -0
- package/dist/builtin/extract/kinds.d.ts +6 -0
- package/dist/builtin/extract/kinds.js +1 -0
- package/dist/builtin/extract/readers.d.ts +7 -0
- package/dist/builtin/extract/readers.js +9 -0
- package/dist/builtin/finish/finish.d.ts +4 -0
- package/dist/builtin/finish/finish.js +1 -1
- package/dist/builtin/http/allow.d.ts +2 -0
- package/dist/builtin/http/allow.js +1 -1
- package/dist/builtin/http/hops.d.ts +10 -0
- package/dist/builtin/http/hops.js +1 -0
- package/dist/builtin/http/http.d.ts +9 -1
- package/dist/builtin/http/http.js +1 -1
- package/dist/builtin/http/index.d.ts +2 -0
- package/dist/builtin/http/index.js +1 -1
- package/dist/builtin/http/retry-after.d.ts +14 -0
- package/dist/builtin/http/retry-after.js +1 -0
- package/dist/builtin/index.d.ts +10 -6
- package/dist/builtin/index.js +1 -1
- package/dist/builtin/json/index.d.ts +1 -0
- package/dist/builtin/json/index.js +1 -1
- package/dist/builtin/json/json.js +1 -1
- package/dist/builtin/json/parse.d.ts +15 -0
- package/dist/builtin/json/parse.js +1 -0
- package/dist/builtin/notes/index.d.ts +1 -0
- package/dist/builtin/notes/index.js +1 -0
- package/dist/builtin/notes/notes.d.ts +45 -0
- package/dist/builtin/notes/notes.js +2 -0
- package/dist/builtin/openalex/api.d.ts +22 -0
- package/dist/builtin/openalex/api.js +1 -0
- package/dist/builtin/openalex/index.d.ts +4 -0
- package/dist/builtin/openalex/index.js +1 -0
- package/dist/builtin/openalex/openalex.d.ts +23 -0
- package/dist/builtin/openalex/openalex.js +1 -0
- package/dist/builtin/openalex/render.d.ts +2 -0
- package/dist/builtin/openalex/render.js +4 -0
- package/dist/builtin/polite.d.ts +14 -0
- package/dist/builtin/polite.js +1 -0
- package/dist/builtin/publish/index.d.ts +1 -0
- package/dist/builtin/publish/index.js +1 -0
- package/dist/builtin/publish/publish.d.ts +46 -0
- package/dist/builtin/publish/publish.js +1 -0
- package/dist/builtin/web-search/web-search.d.ts +10 -35
- package/dist/builtin/web-search/web-search.js +1 -1
- package/dist/builtin/wikidata/api.d.ts +40 -0
- package/dist/builtin/wikidata/api.js +1 -0
- package/dist/builtin/wikidata/index.d.ts +5 -0
- package/dist/builtin/wikidata/index.js +1 -0
- package/dist/builtin/wikidata/render.d.ts +13 -0
- package/dist/builtin/wikidata/render.js +2 -0
- package/dist/builtin/wikidata/wikidata.d.ts +21 -0
- package/dist/builtin/wikidata/wikidata.js +1 -0
- package/dist/bus/bus.d.ts +23 -1
- package/dist/bus/bus.js +1 -1
- package/dist/bus/group.d.ts +14 -1
- package/dist/bus/group.js +1 -1
- package/dist/bus/index.d.ts +4 -1
- package/dist/bus/index.js +1 -1
- package/dist/bus/invoke.d.ts +1 -1
- package/dist/bus/invoke.js +3 -1
- package/dist/bus/namespace.d.ts +21 -0
- package/dist/bus/namespace.js +1 -0
- package/dist/bus/once.d.ts +32 -0
- package/dist/bus/once.js +1 -0
- package/dist/bus/only.d.ts +29 -0
- package/dist/bus/only.js +0 -0
- package/dist/bus/options.d.ts +31 -0
- package/dist/bus/select.d.ts +0 -16
- package/dist/bus/select.js +1 -1
- package/dist/bus/spent.d.ts +16 -0
- package/dist/bus/spent.js +1 -0
- package/dist/bus/trace.d.ts +14 -1
- package/dist/bus/trace.js +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1 -1
- package/dist/internals.d.ts +8 -1
- package/dist/internals.js +1 -1
- package/dist/memories/client.d.ts +91 -0
- package/dist/memories/client.js +0 -0
- package/dist/memories/context.d.ts +5 -0
- package/dist/memories/context.js +1 -0
- package/dist/{builtin → memories}/deep-recall/deep-recall.d.ts +3 -0
- package/dist/memories/deep-recall/deep-recall.js +1 -0
- package/dist/memories/explore/explore.d.ts +18 -0
- package/dist/memories/explore/explore.js +7 -0
- package/dist/memories/explore/subgraph.d.ts +12 -0
- package/dist/memories/explore/subgraph.js +3 -0
- package/dist/memories/index.d.ts +30 -0
- package/dist/memories/index.js +1 -0
- package/dist/memories/observe/observe.d.ts +7 -0
- package/dist/memories/observe/observe.js +1 -0
- package/dist/memories/recall/recall.d.ts +42 -0
- package/dist/memories/recall/recall.js +1 -0
- package/dist/memories/recall/render.d.ts +5 -0
- package/dist/memories/recall/render.js +3 -0
- package/dist/memories/remember/remember.d.ts +49 -0
- package/dist/memories/remember/remember.js +1 -0
- package/dist/search/index.d.ts +5 -0
- package/dist/search/index.js +1 -0
- package/dist/search/retry.d.ts +6 -0
- package/dist/search/retry.js +1 -0
- package/dist/search/search.d.ts +63 -0
- package/dist/search/search.js +1 -0
- package/dist/search/searxng/index.d.ts +2 -0
- package/dist/search/searxng/index.js +1 -0
- package/dist/search/searxng/searxng.d.ts +14 -0
- package/dist/search/searxng/searxng.js +5 -0
- package/dist/search/searxng/text.d.ts +2 -0
- package/dist/search/searxng/text.js +3 -0
- package/dist/search/sonar/index.d.ts +2 -0
- package/dist/search/sonar/index.js +1 -0
- package/dist/search/sonar/sonar.d.ts +13 -0
- package/dist/search/sonar/sonar.js +1 -0
- package/dist/search/tavily/index.d.ts +4 -0
- package/dist/search/tavily/index.js +1 -0
- package/dist/search/tavily/reply.d.ts +22 -0
- package/dist/search/tavily/reply.js +5 -0
- package/dist/search/tavily/tavily.d.ts +14 -0
- package/dist/search/tavily/tavily.js +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +1 -0
- package/dist/testing/replay.d.ts +55 -0
- package/dist/testing/replay.js +1 -0
- package/dist/testing/store.d.ts +35 -0
- package/dist/testing/store.js +4 -0
- package/dist/tool/tool.d.ts +4 -1
- package/dist/tool/tool.js +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/result.d.ts +38 -0
- package/dist/types/tool.d.ts +61 -0
- package/docs/bogus.mdx +85 -0
- package/docs/builtins.mdx +156 -0
- package/docs/bus.mdx +90 -0
- package/docs/declaring.mdx +85 -0
- package/docs/effects.mdx +49 -0
- package/docs/overview.mdx +76 -0
- package/docs/selecting.mdx +79 -0
- package/docs/stored.mdx +83 -0
- package/docs/turns.mdx +57 -0
- package/package.json +22 -9
- package/dist/builtin/deep-recall/deep-recall.js +0 -1
- package/dist/builtin/write-document/commission.js +0 -13
- package/dist/builtin/write-document/index.d.ts +0 -6
- package/dist/builtin/write-document/index.js +0 -1
- package/dist/builtin/write-document/write-document.js +0 -1
- /package/dist/{builtin/write-document → agents/moa}/design.d.ts +0 -0
- /package/dist/{builtin/write-document → agents/moa}/design.js +0 -0
- /package/dist/{builtin/write-document → agents/moa}/http.d.ts +0 -0
- /package/dist/{builtin/write-document → agents/moa}/http.js +0 -0
- /package/dist/{builtin/write-document → agents/moa}/types.js +0 -0
- /package/dist/{builtin → memories}/deep-recall/index.d.ts +0 -0
- /package/dist/{builtin → memories}/deep-recall/index.js +0 -0
- /package/dist/{builtin/web-search → search/sonar}/reply.d.ts +0 -0
- /package/dist/{builtin/web-search → search/sonar}/reply.js +0 -0
package/docs/stored.mdx
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
title: "A stored tool — spendgraph docs",
|
|
3
|
+
description:
|
|
4
|
+
"The dashboard owns the description, your code owns the arguments and the handler, and bindTool checks the two against each other before the model ever sees it.",
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
# A stored tool
|
|
8
|
+
|
|
9
|
+
The description is the biggest lever on whether a model calls a tool correctly, and the part you will want to change most often. `bindTool` puts that half in the dashboard and leaves the rest in code.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { bindTool } from "@spendgraph/tools";
|
|
13
|
+
import { Spendgraph } from "@spendgraph/sdk";
|
|
14
|
+
|
|
15
|
+
const lookup = await bindTool(sg, {
|
|
16
|
+
name: "lookup_contract",
|
|
17
|
+
args: [{ name: "ref", type: "string", required: true }] as const,
|
|
18
|
+
run: ({ ref }) => search(ref),
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
No `description` in that call. That is the point — one source for the string the model reads, and it is the one you can edit without a release.
|
|
23
|
+
|
|
24
|
+
## Who owns what
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
DASHBOARD YOUR CODE
|
|
28
|
+
───────── ─────────
|
|
29
|
+
description ◀── iterate on args ──▶ run() is typed from them
|
|
30
|
+
effect these without run() ──▶ the thing that actually happens
|
|
31
|
+
pinned a deploy
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Arguments stay in code because the handler's parameter types are inferred from them. Pull those from the server and every `run` is handed a `Record<string, unknown>`, which gives up the one guarantee [declaring a tool](/docs/tools/declaring) exists to provide.
|
|
35
|
+
|
|
36
|
+
Write `as const` here exactly as you would for `tool()`. Without it inference falls back to nothing, and the drift check below becomes the only thing still catching a rename.
|
|
37
|
+
|
|
38
|
+
## Drift fails at bind, not mid-loop
|
|
39
|
+
|
|
40
|
+
The stored arguments and the declared ones are compared on the way through, by **name, type and requiredness** — the three a handler is written against.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { ToolDriftError, ToolNotStoredError } from "@spendgraph/tools";
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await bindTool(sg, spec);
|
|
47
|
+
} catch (err) {
|
|
48
|
+
if (err instanceof ToolDriftError) err.differences; // every disagreement, in words
|
|
49
|
+
if (err instanceof ToolNotStoredError) err.toolName; // nothing stored under that name
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`differences` reads like a review comment rather than a diff:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
"ref" is string here and number stored
|
|
57
|
+
"limit" is declared here but not stored
|
|
58
|
+
"mode" is stored but not declared here
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A description or a bound that differs is **not** drift — that is the dashboard being edited, which is the whole feature. A renamed argument is a handler about to be passed `undefined` halfway through an agent loop, so it throws.
|
|
62
|
+
|
|
63
|
+
<Callout tone="warn" title="Bind at startup, not per request">
|
|
64
|
+
Every `bindTool` is a round trip to the API. Bind once when the process starts and hold the result, the same as you would a database connection — a bind inside a request handler puts a network hop in front of every model call.
|
|
65
|
+
</Callout>
|
|
66
|
+
|
|
67
|
+
<Callout tone="trap" title="A rename in the dashboard is a handler passed `undefined`">
|
|
68
|
+
The wording is editable without a deploy; the argument names are not. `bindTool` compares them at bind time and refuses — a deploy that fails is recoverable, and the same rename noticed mid-loop is a handler halfway through somebody's refund reading an argument that is not there.
|
|
69
|
+
</Callout>
|
|
70
|
+
|
|
71
|
+
## When nothing is stored yet
|
|
72
|
+
|
|
73
|
+
`ToolNotStoredError` is the ordinary case of "you have not written this one in the dashboard yet", not an exotic failure. It exists so a 404 from three layers down arrives as a sentence naming the tool.
|
|
74
|
+
|
|
75
|
+
Create the row first — `sg.tools.create` on the [client](/docs/sdk/client), or the Tools page in the dashboard — then bind to it.
|
|
76
|
+
|
|
77
|
+
## It is an ordinary tool afterwards
|
|
78
|
+
|
|
79
|
+
What comes back is what `tool()` returns. Register it on a bus, select it, invoke it, record it; nothing downstream knows or cares where the wording came from.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
const bus = toolbus([lookup, calculate()]);
|
|
83
|
+
```
|
package/docs/turns.mdx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const meta = {
|
|
2
|
+
title: "A turn — spendgraph docs",
|
|
3
|
+
description:
|
|
4
|
+
"A turn is selected once and remembers what it offered. Without that a record cannot tell 'chose not to' from 'was never offered', which are opposite bugs.",
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
# A turn
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
const turn = bus.trace(query);
|
|
11
|
+
|
|
12
|
+
const reply = await llm.call(messages, { tools: turn });
|
|
13
|
+
await turn.invoke(call.name, call.args);
|
|
14
|
+
|
|
15
|
+
turn.record(); // { offeredTools, steps }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
A turn is **selected once** and remembers what it offered. A trace cannot disagree with itself about what the model saw.
|
|
19
|
+
|
|
20
|
+
## Offered is recorded, not just called
|
|
21
|
+
|
|
22
|
+
Which tools were offered is recorded as well as which were called. Without it a record cannot tell **"chose not to"** from **"was never offered"** — which are opposite bugs, and look identical in a log that only lists calls.
|
|
23
|
+
|
|
24
|
+
## What a turn answers
|
|
25
|
+
|
|
26
|
+
| | |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `turn.offered` | the shortlist this turn was given |
|
|
29
|
+
| `turn.anthropic()` · `openai()` · `markdown()` | the same list, per provider |
|
|
30
|
+
| `turn.effectOf(name)` | what that tool said it does, or `undefined` |
|
|
31
|
+
| `turn.invoke(name, args)` | runs one and records the step. Never throws |
|
|
32
|
+
| `turn.steps()` | the steps so far, in call order |
|
|
33
|
+
| `turn.record()` | the pair, in the shape `report` takes |
|
|
34
|
+
|
|
35
|
+
## Never throwing is the point
|
|
36
|
+
|
|
37
|
+
A tool that fails is an **outcome the agent can react to** and a step worth recording, not an exception that ends the run — the same argument `status` and `error` exist on a rollout for.
|
|
38
|
+
|
|
39
|
+
A tool the bus does not have is a failure that says what was offered, since the usual cause is a hallucinated name.
|
|
40
|
+
|
|
41
|
+
<Callout tone="trap" title="`undefined` means two different things">
|
|
42
|
+
A tool that was offered and stayed quiet, and a tool this turn never offered, both answer `undefined`. `offeredTools` is what tells them apart — which is the difference between a model that declined to look something up and a model that could not.
|
|
43
|
+
</Callout>
|
|
44
|
+
|
|
45
|
+
## Usage drives the tiebreaker
|
|
46
|
+
|
|
47
|
+
`bus.usage()` counts what has actually been called, which is what selection falls back on when a query singles out nothing. A call that never reached the tool — a name that does not exist, arguments that did not validate — is not counted, because it was not a use.
|
|
48
|
+
|
|
49
|
+
## With a prompt
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
await prompt.call(values, ({ messages, turn }) => llm.call(messages, { tools: turn }), {
|
|
53
|
+
tools: bus,
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The prompt hands the turn to your callback and puts `record()` on the rollout. The three packages compose without any of them importing another.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spendgraph/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Declare a tool once, offer the right few, and record what was called.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"types": "./dist/index.d.ts",
|
|
29
29
|
"import": "./dist/index.js"
|
|
30
30
|
},
|
|
31
|
+
"./docs/*": "./docs/*",
|
|
31
32
|
"./bogus": {
|
|
32
33
|
"types": "./dist/bogus/index.d.ts",
|
|
33
34
|
"import": "./dist/bogus/index.js"
|
|
@@ -36,6 +37,14 @@
|
|
|
36
37
|
"types": "./dist/wire/index.d.ts",
|
|
37
38
|
"import": "./dist/wire/index.js"
|
|
38
39
|
},
|
|
40
|
+
"./search": {
|
|
41
|
+
"types": "./dist/search/index.d.ts",
|
|
42
|
+
"import": "./dist/search/index.js"
|
|
43
|
+
},
|
|
44
|
+
"./testing": {
|
|
45
|
+
"types": "./dist/testing/index.d.ts",
|
|
46
|
+
"import": "./dist/testing/index.js"
|
|
47
|
+
},
|
|
39
48
|
"./internals": {
|
|
40
49
|
"types": "./dist/internals.d.ts",
|
|
41
50
|
"import": "./dist/internals.js"
|
|
@@ -44,19 +53,18 @@
|
|
|
44
53
|
},
|
|
45
54
|
"files": [
|
|
46
55
|
"dist",
|
|
56
|
+
"docs",
|
|
47
57
|
"README.md"
|
|
48
58
|
],
|
|
49
|
-
"scripts": {
|
|
50
|
-
"build": "rm -rf dist && tsc -p tsconfig.json --emitDeclarationOnly && tsc -p tsconfig.json --declaration false --removeComments && node ../../scripts/minify.mjs dist",
|
|
51
|
-
"test": "npm run build && vitest run",
|
|
52
|
-
"examples": "npm run build && node examples/02-select/01-shortlist.mjs"
|
|
53
|
-
},
|
|
54
59
|
"dependencies": {
|
|
55
|
-
"@spendgraph/sdk": "^0.
|
|
60
|
+
"@spendgraph/sdk": "^0.7.0",
|
|
61
|
+
"jszip": "^3.10.2",
|
|
62
|
+
"unpdf": "^1.8.1"
|
|
56
63
|
},
|
|
57
64
|
"devDependencies": {
|
|
58
65
|
"@locusgraph/client": "^0.8.1",
|
|
59
|
-
"@spendgraph/prompt": "^0.
|
|
66
|
+
"@spendgraph/prompt": "^0.7.0",
|
|
67
|
+
"pdf-lib": "^1.17.1",
|
|
60
68
|
"typescript": "^5"
|
|
61
69
|
},
|
|
62
70
|
"engines": {
|
|
@@ -64,5 +72,10 @@
|
|
|
64
72
|
},
|
|
65
73
|
"publishConfig": {
|
|
66
74
|
"access": "public"
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"build": "rm -rf dist && tsc -p tsconfig.json --emitDeclarationOnly && tsc -p tsconfig.json --declaration false --removeComments && node ../../scripts/minify.mjs dist",
|
|
78
|
+
"test": "vitest run",
|
|
79
|
+
"examples": "pnpm run build && node examples/02-select/01-shortlist.mjs"
|
|
67
80
|
}
|
|
68
|
-
}
|
|
81
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{tool as s}from"../../tool/index.js";const o=20;function l(t){const a=t.maxFacts??o;return s({name:"deep_recall",description:"Searches your own knowledge base and returns an answer with the evidence it rests on. A walker follows linked contexts, so it answers questions spread across several notes \u2014 what do we know about X, what was decided and why. Ask one focused thing. Prefer it over a web search whenever the answer could already be in your records.",effect:"readonly",args:[{name:"question",type:"string",required:!0,maxLength:1e3,description:"One focused question, not a conversation and not several at once."},{name:"context_ids",type:"list",required:!1,description:"Contexts to start the walk from, as type:name \u2014 take them from the contexts of an earlier result. A hint, not a filter; the walk may go elsewhere."}],run:async({question:n,context_ids:r})=>{const e=await t.client.deepRecall({question:n,...t.graphId?{graphId:t.graphId}:{},...r?.length?{contextIds:r}:{}});return{summary:e.summary,facts:e.facts.slice(0,a),truncated:e.facts.length>a,contextsWalked:e.contexts_walked,coverage:e.coverage,fallback:e.fallback,costMicroUsd:Math.round(e.usage.cost_usd*1e6)}}})}export{l as deepRecall};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{createRequest as w,MoaApiError as h}from"./http.js";const T={queued:"pending",running:"running",succeeded:"done",failed:"failed",canceled:"failed"},M=["md","pdf","docx","pptx"],g=n=>{const t=n?.split(".").pop()?.toLowerCase();return t&&M.includes(t)?t:void 0};function E(n){if(!n?.length)return;const t=n.flatMap(e=>{const s=g(e.name);return!s||!(e.url||e.data)?[]:[{name:e.name??`document.${s}`,format:s,url:e.url,data:e.data,mime:e.contentType,sizeBytes:e.sizeBytes}]});return t.length?t:void 0}function I(n){return`
|
|
2
|
-
|
|
3
|
-
<deliverables>
|
|
4
|
-
Besides the text answer, save the finished deliverable into the artifacts/ directory of your working dir as: ${n.map(t=>`one .${t} file`).join(", ")}.
|
|
5
|
-
</deliverables>`}function x(n){let t=n.task;return n.context&&(t+=`
|
|
6
|
-
|
|
7
|
-
<context>
|
|
8
|
-
${n.context}
|
|
9
|
-
</context>`),n.design&&(t+=`
|
|
10
|
-
|
|
11
|
-
<design>
|
|
12
|
-
${n.design}
|
|
13
|
-
</design>`),n.artifacts?.length&&(t+=I(n.artifacts)),t}function _(n={}){const t=w(n);return{async create(e){const s=await t("/tasks",{method:"POST",body:{task:x(e),mode:"striker",...e.sessionId?{sessionId:e.sessionId}:{},...e.newSessionId?{newSessionId:e.newSessionId}:{}}});if(!s.id)throw new h("Moa did not return a task id",502);return s.id},async get(e,s){const c=s?.waitMs&&s.waitMs>0?`?waitMs=${Math.floor(s.waitMs)}`:"",o=await t(`/tasks/${encodeURIComponent(e)}${c}`,{signal:s?.signal}),i=o.status?T[o.status]:void 0;return{id:o.id??e,status:i??"running",output:o.result,error:o.error,costUsd:o.costUsd,numTurns:o.numTurns,sessionId:o.sessionId,artifacts:E(o.artifacts)}},async cancel(e){await t(`/tasks/${encodeURIComponent(e)}`,{method:"DELETE"})}}}const b=3e4,A=2e3,k=3,y=25e3;class m extends Error{commissionId;constructor(t){super(`Commission ${t} was cancelled by the caller.`),this.name="CommissionAbortedError",this.commissionId=t}}class C extends Error{commissionId;timeoutMs;constructor(t,e){super(`Commission ${t} did not complete within ${e/1e3}s. The task may still be running in the background.`),this.name="CommissionTimeoutError",this.commissionId=t,this.timeoutMs=e}}const f=(n,t)=>new Promise(e=>{const s=()=>e();t?.addEventListener("abort",s,{once:!0}),setTimeout(()=>{t?.removeEventListener("abort",s),e()},n)});async function p(n,t,e={}){const s=e.timeoutMs??b,c=e.pollIntervalMs??A,o=e.settleMs??0,i=e.signal,l=Date.now()+s;for(;;){if(i?.aborted)throw new m(t);const u=l-Date.now();if(u<=0)throw new C(t,s);let r;try{r=await n.get(t,{waitMs:Math.min(u,y),signal:i})}catch(d){throw i?.aborted?new m(t):d}if(r.status==="failed")return r;if(r.status==="done"){const d=a=>!a.output?.trim()||e.expectArtifacts===!0&&!a.artifacts?.length;for(let a=0;o>0&&a<k&&d(r);a++)await f(o),r=await n.get(t);return r}await f(Math.min(c,Math.max(0,l-Date.now())),i)}}export{m as CommissionAbortedError,C as CommissionTimeoutError,b as INTERACTIVE_TIMEOUT_MS,_ as createCommissionClient,p as pollUntilDone};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export type { CommissionClient, PollOptions } from "./commission.js";
|
|
2
|
-
export { CommissionAbortedError, CommissionTimeoutError, createCommissionClient, INTERACTIVE_TIMEOUT_MS, pollUntilDone, } from "./commission.js";
|
|
3
|
-
export { DEFAULT_DESIGN, type DesignGuide, mergeDesign, renderDesign } from "./design.js";
|
|
4
|
-
export { MOA_BASE_URL, MoaApiError, type MoaClientConfig } from "./http.js";
|
|
5
|
-
export type { ArtifactFormat, CommissionArtifact, CommissionInput, CommissionResult, CommissionStatus, } from "./types.js";
|
|
6
|
-
export { type WriteDocumentOptions, writeDocument } from "./write-document.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{CommissionAbortedError as e,CommissionTimeoutError as i,createCommissionClient as m,INTERACTIVE_TIMEOUT_MS as t,pollUntilDone as n}from"./commission.js";import{DEFAULT_DESIGN as s,mergeDesign as p,renderDesign as A}from"./design.js";import{MOA_BASE_URL as T,MoaApiError as C}from"./http.js";import{writeDocument as f}from"./write-document.js";export{e as CommissionAbortedError,i as CommissionTimeoutError,s as DEFAULT_DESIGN,t as INTERACTIVE_TIMEOUT_MS,T as MOA_BASE_URL,C as MoaApiError,m as createCommissionClient,p as mergeDesign,n as pollUntilDone,A as renderDesign,f as writeDocument};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{tool as f}from"../../tool/index.js";import{CommissionAbortedError as l,CommissionTimeoutError as h,createCommissionClient as g,pollUntilDone as p}from"./commission.js";import{DEFAULT_DESIGN as w,mergeDesign as y,renderDesign as _}from"./design.js";const x=["pdf","pptx","docx","md"],b=6e5,M=2e3,U=4e3;function v(e,i){return`Commissions a document agent to write and render a finished file \u2014 ${e.map(t=>`.${t}`).join(", ")} \u2014 and hands back where to download it. Use it when the answer has to be a document somebody opens: a report, a deck, a proposal, a one-pager. Not for text you can simply write in your reply. It runs for minutes and it costs money, so brief it once and brief it fully \u2014 the agent cannot see this conversation, so every fact, figure and quote it must use goes in \`source\`. Design is already settled by ${i.name??"the house style"}; use \`design_notes\` only for what this one document must do differently.`}function E(e,i,t,d){const r=(e.artifacts??[]).map(o=>({name:o.name,format:o.format,url:o.url,mime:o.mime,sizeBytes:o.sizeBytes,...d&&o.data?{data:o.data}:{}}));return{taskId:e.id,sessionId:e.sessionId,status:"done",style:i,documents:r,delivered:r.length>0,writeUp:e.output?.slice(0,t),truncated:(e.output?.length??0)>t,turns:e.numTurns,costMicroUsd:e.costUsd===void 0?void 0:Math.round(e.costUsd*1e6)}}function T(e,i,t){return{taskId:e,status:"running",style:i,documents:[],delivered:!1,note:`Still rendering after ${Math.round(t.timeoutMs/1e3)}s. The task is not lost \u2014 say so rather than commissioning it again.`}}function L(e){if(!e.client&&!e.apiKey?.trim())throw new Error("writeDocument needs a Moa apiKey; it will not read one from the process.");const i=e.formats?.length?e.formats:x,t=y(w,e.design),d=e.maxChars??U,r=e.client??g({apiKey:e.apiKey,baseUrl:e.baseUrl,...e.fetch?{fetch:e.fetch}:{}});return f({name:"write_document",description:v(i,t),effect:"destructive",args:[{name:"brief",type:"text",required:!0,maxLength:8e3,description:"What to produce, who reads it, what it must cover and how long it runs. Write it as you would brief a person who knows the craft and nothing about this account."},{name:"format",type:"enum",required:!0,options:["pdf","pptx","docx","md"],description:"pptx for anything presented, pdf for anything sent, docx for anything edited."},{name:"source",type:"text",required:!1,maxLength:4e4,description:"The material it must build from \u2014 figures, findings, quotes, an outline \u2014 verbatim. Anything missing here the agent will either omit or invent."},{name:"design_notes",type:"text",required:!1,maxLength:2e3,description:"How this one document departs from the house style, in plain words. Leave it empty unless the user asked for something specific."},{name:"session_id",type:"string",required:!1,description:"Continue an earlier write_document instead of starting over \u2014 take it from that result's sessionId. Use it to revise a document or to recast one into another format."}],run:async({brief:o,format:s,source:u,design_notes:m,session_id:c})=>{if(!i.includes(s))throw new Error(`write_document was asked for .${s}, which this deployment does not produce (${i.map(n=>`.${n}`).join(", ")}).`);const a=await r.create({task:o,context:u,design:_(t,s,m),artifacts:[s],...c?{sessionId:c}:{}});try{const n=await p(r,a,{timeoutMs:e.timeoutMs??b,settleMs:M,expectArtifacts:!0,...e.signal?{signal:e.signal}:{}});if(n.status==="failed")throw new Error(`write_document: Moa task ${a} failed: ${n.error??"no reason given"}`);return E(n,t.name,d,e.includeData===!0)}catch(n){if(n instanceof l&&e.cancelOnAbort!==!1&&await r.cancel?.(a).catch(()=>{}),n instanceof h)return T(a,t.name,n);throw n}}})}export{L as writeDocument};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|