@adia-ai/agent 0.8.26
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/CHANGELOG.md +7 -0
- package/README.md +172 -0
- package/agent.d.ts +53 -0
- package/agent.d.ts.map +1 -0
- package/agent.js +99 -0
- package/agent.js.map +1 -0
- package/events.d.ts +92 -0
- package/events.d.ts.map +1 -0
- package/events.js +112 -0
- package/events.js.map +1 -0
- package/frame.d.ts +60 -0
- package/frame.d.ts.map +1 -0
- package/frame.js +43 -0
- package/frame.js.map +1 -0
- package/index.d.ts +28 -0
- package/index.d.ts.map +1 -0
- package/index.js +18 -0
- package/index.js.map +1 -0
- package/integrations.d.ts +105 -0
- package/integrations.d.ts.map +1 -0
- package/integrations.js +167 -0
- package/integrations.js.map +1 -0
- package/loop.d.ts +44 -0
- package/loop.d.ts.map +1 -0
- package/loop.js +120 -0
- package/loop.js.map +1 -0
- package/package.json +41 -0
- package/prompt.d.ts +36 -0
- package/prompt.d.ts.map +1 -0
- package/prompt.js +38 -0
- package/prompt.js.map +1 -0
- package/resource.d.ts +27 -0
- package/resource.d.ts.map +1 -0
- package/resource.js +46 -0
- package/resource.js.map +1 -0
- package/session.d.ts +30 -0
- package/session.d.ts.map +1 -0
- package/session.js +30 -0
- package/session.js.map +1 -0
- package/stub.d.ts +22 -0
- package/stub.d.ts.map +1 -0
- package/stub.js +52 -0
- package/stub.js.map +1 -0
- package/tools.d.ts +43 -0
- package/tools.d.ts.map +1 -0
- package/tools.js +103 -0
- package/tools.js.map +1 -0
- package/workflow.d.ts +44 -0
- package/workflow.d.ts.map +1 -0
- package/workflow.js +36 -0
- package/workflow.js.map +1 -0
package/frame.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* frameClientMessage / shouldRunTurn — law 6: framed client-message turns.
|
|
3
|
+
*
|
|
4
|
+
* The session is a plain serializable turn array (session.ts); every
|
|
5
|
+
* surface action, function/tool result, and validation rejection re-enters
|
|
6
|
+
* the loop as a *distinct natural-language user turn* through this ONE
|
|
7
|
+
* framing function — never scattered ad-hoc string-building at call sites.
|
|
8
|
+
*
|
|
9
|
+
* Silent-apply kinds (a data-model echo, an action-response ack the caller
|
|
10
|
+
* already consumed) never construct a turn at all: `shouldRunTurn` gates
|
|
11
|
+
* them out BEFORE framing is attempted, and `frameClientMessage` itself
|
|
12
|
+
* THROWS if handed one directly — a should-not-run message is
|
|
13
|
+
* unconstructable as a turn, not merely skipped. This mirrors the wire's
|
|
14
|
+
* own three-arm client vocabulary (action / error / functionResponse) one
|
|
15
|
+
* level up, in plain language the model reads as a user turn.
|
|
16
|
+
*/
|
|
17
|
+
const SILENT_APPLY_KINDS = new Set(['dataModelUpdate', 'ack']);
|
|
18
|
+
/** Gate BEFORE framing: false means this message applies silently and must
|
|
19
|
+
* never reach `frameClientMessage`. */
|
|
20
|
+
export function shouldRunTurn(msg) {
|
|
21
|
+
return !SILENT_APPLY_KINDS.has(msg.kind);
|
|
22
|
+
}
|
|
23
|
+
/** Maps one client-message arm to its pinned natural-language user turn.
|
|
24
|
+
* Deterministic — same input, same string, always — so golden tests can
|
|
25
|
+
* pin the exact wording. Throws for any kind `shouldRunTurn` rejects. */
|
|
26
|
+
export function frameClientMessage(msg) {
|
|
27
|
+
switch (msg.kind) {
|
|
28
|
+
case 'surfaceAction':
|
|
29
|
+
return `The user triggered the ${msg.action} action on surface ${msg.surfaceId} with context ${JSON.stringify(msg.context ?? null)}.`;
|
|
30
|
+
case 'functionResult':
|
|
31
|
+
return `The function ${msg.call} returned: ${JSON.stringify(msg.value)}.`;
|
|
32
|
+
case 'validationRejection':
|
|
33
|
+
return `The previous surface was rejected (${msg.code}): ${msg.message}. Emit a corrected surface.`;
|
|
34
|
+
case 'dataModelUpdate':
|
|
35
|
+
case 'ack':
|
|
36
|
+
throw new Error(`frameClientMessage: "${msg.kind}" is silent-apply — gate with shouldRunTurn() before framing`);
|
|
37
|
+
default: {
|
|
38
|
+
const unreachable = msg;
|
|
39
|
+
throw new Error(`frameClientMessage: unknown kind "${unreachable.kind}"`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=frame.js.map
|
package/frame.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame.js","sourceRoot":"","sources":["src/frame.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAkBH,MAAM,kBAAkB,GAAuC,IAAI,GAAG,CAAC,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnG;wCACwC;AACxC,MAAM,UAAU,aAAa,CAAC,GAAkB;IAC9C,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED;;0EAE0E;AAC1E,MAAM,UAAU,kBAAkB,CAAC,GAAkB;IACnD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,eAAe;YAClB,OAAO,0BAA0B,GAAG,CAAC,MAAM,sBAAsB,GAAG,CAAC,SAAS,iBAAiB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC;QAExI,KAAK,gBAAgB;YACnB,OAAO,gBAAgB,GAAG,CAAC,IAAI,cAAc,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;QAE5E,KAAK,qBAAqB;YACxB,OAAO,sCAAsC,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,OAAO,6BAA6B,CAAC;QAEtG,KAAK,iBAAiB,CAAC;QACvB,KAAK,KAAK;YACR,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,CAAC,IAAI,8DAA8D,CAC/F,CAAC;QAEJ,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,GAAG,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,qCAAsC,WAA6B,CAAC,IAAI,GAAG,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adia-ai/agent — composable chat-agent harness for AdiaUI.
|
|
3
|
+
*
|
|
4
|
+
* Assemble an agent from four declared parts on top of @adia-ai/llm:
|
|
5
|
+
* prompt layers, tools, workflows, resources. Owns the tool-call loop,
|
|
6
|
+
* the serializable Session, and the one shared event reducer.
|
|
7
|
+
*/
|
|
8
|
+
export { createAgent } from './agent.js';
|
|
9
|
+
export type { Agent, AgentConfig, SendOpts } from './agent.js';
|
|
10
|
+
export { promptLayer, composeSystem } from './prompt.js';
|
|
11
|
+
export type { PromptLayer, ComposedSystem } from './prompt.js';
|
|
12
|
+
export { defineTool, executeTool, checkInput, toSpecs } from './tools.js';
|
|
13
|
+
export type { ToolDef, ToolContext, ToolOutcome } from './tools.js';
|
|
14
|
+
export { defineWorkflow, runWorkflow } from './workflow.js';
|
|
15
|
+
export type { Workflow, WorkflowStep, WorkflowContext, WorkflowResult } from './workflow.js';
|
|
16
|
+
export { defineResource } from './resource.js';
|
|
17
|
+
export type { ResourceDef } from './resource.js';
|
|
18
|
+
export { createIntegrationRegistry, resolveIntegrations, buildToolDispatch, MAX_INTEGRATIONS } from './integrations.js';
|
|
19
|
+
export type { IntegrationManifest, IntegrationRegistry, IntegrationContext, ResolvedIntegrations } from './integrations.js';
|
|
20
|
+
export { createSession, toJSON, fromJSON } from './session.js';
|
|
21
|
+
export type { Session, Msg, Draft } from './session.js';
|
|
22
|
+
export { reduce, reduceAll, PROGRESS_STAGES, isProgressStage } from './events.js';
|
|
23
|
+
export type { AgentEvent, ProgressStage } from './events.js';
|
|
24
|
+
export { frameClientMessage, shouldRunTurn } from './frame.js';
|
|
25
|
+
export type { ClientMessage } from './frame.js';
|
|
26
|
+
export { scriptClient } from './stub.js';
|
|
27
|
+
export type { ScriptedTurn, ScriptClient } from './stub.js';
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1E,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5D,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxH,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC5H,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClF,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @adia-ai/agent — composable chat-agent harness for AdiaUI.
|
|
3
|
+
*
|
|
4
|
+
* Assemble an agent from four declared parts on top of @adia-ai/llm:
|
|
5
|
+
* prompt layers, tools, workflows, resources. Owns the tool-call loop,
|
|
6
|
+
* the serializable Session, and the one shared event reducer.
|
|
7
|
+
*/
|
|
8
|
+
export { createAgent } from './agent.js';
|
|
9
|
+
export { promptLayer, composeSystem } from './prompt.js';
|
|
10
|
+
export { defineTool, executeTool, checkInput, toSpecs } from './tools.js';
|
|
11
|
+
export { defineWorkflow, runWorkflow } from './workflow.js';
|
|
12
|
+
export { defineResource } from './resource.js';
|
|
13
|
+
export { createIntegrationRegistry, resolveIntegrations, buildToolDispatch, MAX_INTEGRATIONS } from './integrations.js';
|
|
14
|
+
export { createSession, toJSON, fromJSON } from './session.js';
|
|
15
|
+
export { reduce, reduceAll, PROGRESS_STAGES, isProgressStage } from './events.js';
|
|
16
|
+
export { frameClientMessage, shouldRunTurn } from './frame.js';
|
|
17
|
+
export { scriptClient } from './stub.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAExH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElF,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integrations — the tier-2 (machine-callable) tool registry.
|
|
3
|
+
*
|
|
4
|
+
* CHAT-HARNESS law 5 draws a line between two different things that both
|
|
5
|
+
* end up as prompt/tool material: config-level tool ENTRIES (tier 1, prose,
|
|
6
|
+
* no schema, live in L2) and machine-callable INTEGRATIONS (tier 2, this
|
|
7
|
+
* module) — a typed manifest with a real JSON-Schema input, boot-time
|
|
8
|
+
* fail-fast registration, and schema-validated dispatch. `defineTool` in
|
|
9
|
+
* ./tools.js is the tier-2 wire shape this module compiles down to.
|
|
10
|
+
*
|
|
11
|
+
* An IntegrationManifest carries three INDEPENDENT facts, never conflated:
|
|
12
|
+
* - `id` — enablement vocabulary (what a persona's entry list or a
|
|
13
|
+
* settings UI toggles on/off; stable across renames).
|
|
14
|
+
* - `tool.name` — the wire name the MODEL calls (goes on the ToolSpec).
|
|
15
|
+
* - `label` — the DISPLAY name a human sees in a picker or a dropped-
|
|
16
|
+
* integration notice.
|
|
17
|
+
* Renaming a tool's wire name (a prompt-engineering concern) must never
|
|
18
|
+
* silently re-enable or disable it; renaming its display label must never
|
|
19
|
+
* touch dispatch. Keeping them apart is the whole point of the type.
|
|
20
|
+
*
|
|
21
|
+
* The pipeline is three pure stages:
|
|
22
|
+
* register → boot-fail-fast (throws — a bad manifest never reaches
|
|
23
|
+
* runtime)
|
|
24
|
+
* resolve → per-request, per-persona: enabledIds ∩ registry, capped,
|
|
25
|
+
* unprovisioned serverKey manifests DROPPED (never a
|
|
26
|
+
* mid-turn failure — a missing key degrades to "not
|
|
27
|
+
* offered" and is reported back for UI display)
|
|
28
|
+
* buildDispatch → the ONE place a resolved manifest becomes a ToolDef,
|
|
29
|
+
* closing over the env-var NAME (never the key value) so
|
|
30
|
+
* the key is read fresh at call time and never serialized
|
|
31
|
+
* onto the manifest object or persisted anywhere.
|
|
32
|
+
*
|
|
33
|
+
* Law 8: when a second (server-side) host consumes this registry — a proxy
|
|
34
|
+
* or worker dispatching tool calls outside the browser — the env-var
|
|
35
|
+
* resolution and the drop-on-unprovisioned rule this module owns must
|
|
36
|
+
* extract to a shared place in THAT change, not be hand-duplicated. Nothing
|
|
37
|
+
* here assumes a browser; `env` is passed in, never read from a global.
|
|
38
|
+
*/
|
|
39
|
+
import { type ToolContext, type ToolDef } from './tools.js';
|
|
40
|
+
export interface IntegrationManifest {
|
|
41
|
+
/** Enablement vocabulary — what a persona/settings UI toggles. */
|
|
42
|
+
id: string;
|
|
43
|
+
tool: {
|
|
44
|
+
/** The wire name the model calls. Independent of `id` and `label`. */
|
|
45
|
+
name: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
inputSchema: Record<string, unknown>;
|
|
48
|
+
};
|
|
49
|
+
/** Display name for a human (picker, dropped-integration notice). */
|
|
50
|
+
label: string;
|
|
51
|
+
auth?: {
|
|
52
|
+
kind: 'serverKey';
|
|
53
|
+
envKey: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'none';
|
|
56
|
+
};
|
|
57
|
+
execute: (input: Record<string, unknown>, ctx: IntegrationContext) => unknown | Promise<unknown>;
|
|
58
|
+
}
|
|
59
|
+
/** ToolContext plus the resolved server key for THIS dispatch — present
|
|
60
|
+
* only when `auth.kind === 'serverKey'` and the env var was set (an unset
|
|
61
|
+
* one never reaches here: resolveIntegrations already dropped it). */
|
|
62
|
+
export interface IntegrationContext extends ToolContext {
|
|
63
|
+
key?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface IntegrationRegistry {
|
|
66
|
+
/** Boot-fail-fast: throws on a duplicate id, a duplicate tool.name, an
|
|
67
|
+
* inputSchema outside checkInput's supported subset, or a serverKey auth
|
|
68
|
+
* with a missing/empty envKey. Returns the manifest on success. */
|
|
69
|
+
register(manifest: IntegrationManifest): IntegrationManifest;
|
|
70
|
+
get(id: string): IntegrationManifest | undefined;
|
|
71
|
+
list(): IntegrationManifest[];
|
|
72
|
+
}
|
|
73
|
+
export declare function createIntegrationRegistry(): IntegrationRegistry;
|
|
74
|
+
/** Documented cap — resolveIntegrations never hands more than this many
|
|
75
|
+
* manifests to one dispatch, regardless of how many a persona enables. */
|
|
76
|
+
export declare const MAX_INTEGRATIONS = 16;
|
|
77
|
+
export interface ResolvedIntegrations {
|
|
78
|
+
resolved: IntegrationManifest[];
|
|
79
|
+
/** Enabled-but-unusable manifests, reported (not thrown) for UI display —
|
|
80
|
+
* a dropped manifest degrades to "not offered", never a mid-turn error. */
|
|
81
|
+
dropped: Array<{
|
|
82
|
+
id: string;
|
|
83
|
+
reason: string;
|
|
84
|
+
}>;
|
|
85
|
+
}
|
|
86
|
+
/** enabledIds ∩ registry, capped at MAX_INTEGRATIONS, then any serverKey
|
|
87
|
+
* manifest whose env var is unset in `env` is dropped (reason reported).
|
|
88
|
+
* Order matches the contract's own wording: intersect → cap → drop, so a
|
|
89
|
+
* persona enabling more than the cap never sees a key-provisioning check
|
|
90
|
+
* applied to an integration it wouldn't have gotten a slot for anyway. */
|
|
91
|
+
export declare function resolveIntegrations(registry: IntegrationRegistry, enabledIds: string[], env: Record<string, string | undefined>): ResolvedIntegrations;
|
|
92
|
+
/** The ONE place resolved manifests become `{ tools: ToolDef[] }` for
|
|
93
|
+
* AgentConfig. Each ToolDef's `execute` closes over `env` and the auth's
|
|
94
|
+
* envKey NAME only — the key VALUE is read fresh from `env` at call time,
|
|
95
|
+
* never stored on the manifest, never serialized. Schema validation is
|
|
96
|
+
* NOT repeated here: `executeTool` (tools.js, driving every ToolDef
|
|
97
|
+
* through the loop) already runs `checkInput` before invoking `execute` —
|
|
98
|
+
* wrapping it again here would check twice for one call. Zero resolved
|
|
99
|
+
* manifests returns `{}` (no `tools` key at all), so an agent with no
|
|
100
|
+
* integrations enabled produces the exact same AgentConfig, and the same
|
|
101
|
+
* outbound request, as one that never knew integrations existed (law 2). */
|
|
102
|
+
export declare function buildToolDispatch(resolved: IntegrationManifest[], env: Record<string, string | undefined>): {
|
|
103
|
+
tools: ToolDef[];
|
|
104
|
+
} | Record<string, never>;
|
|
105
|
+
//# sourceMappingURL=integrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrations.d.ts","sourceRoot":"","sources":["src/integrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAc,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAExE,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE;QACJ,sEAAsE;QACtE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACtC,CAAC;IACF,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,kBAAkB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClG;AAED;;uEAEuE;AACvE,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC;;wEAEoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,mBAAmB,CAAC;IAC7D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAAC;IACjD,IAAI,IAAI,mBAAmB,EAAE,CAAC;CAC/B;AAyCD,wBAAgB,yBAAyB,IAAI,mBAAmB,CAoC/D;AAED;2EAC2E;AAC3E,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC;gFAC4E;IAC5E,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED;;;;2EAI2E;AAC3E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,mBAAmB,EAC7B,UAAU,EAAE,MAAM,EAAE,EACpB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,oBAAoB,CAyBtB;AAED;;;;;;;;;6EAS6E;AAC7E,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC;IAAE,KAAK,EAAE,OAAO,EAAE,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAY9C"}
|
package/integrations.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integrations — the tier-2 (machine-callable) tool registry.
|
|
3
|
+
*
|
|
4
|
+
* CHAT-HARNESS law 5 draws a line between two different things that both
|
|
5
|
+
* end up as prompt/tool material: config-level tool ENTRIES (tier 1, prose,
|
|
6
|
+
* no schema, live in L2) and machine-callable INTEGRATIONS (tier 2, this
|
|
7
|
+
* module) — a typed manifest with a real JSON-Schema input, boot-time
|
|
8
|
+
* fail-fast registration, and schema-validated dispatch. `defineTool` in
|
|
9
|
+
* ./tools.js is the tier-2 wire shape this module compiles down to.
|
|
10
|
+
*
|
|
11
|
+
* An IntegrationManifest carries three INDEPENDENT facts, never conflated:
|
|
12
|
+
* - `id` — enablement vocabulary (what a persona's entry list or a
|
|
13
|
+
* settings UI toggles on/off; stable across renames).
|
|
14
|
+
* - `tool.name` — the wire name the MODEL calls (goes on the ToolSpec).
|
|
15
|
+
* - `label` — the DISPLAY name a human sees in a picker or a dropped-
|
|
16
|
+
* integration notice.
|
|
17
|
+
* Renaming a tool's wire name (a prompt-engineering concern) must never
|
|
18
|
+
* silently re-enable or disable it; renaming its display label must never
|
|
19
|
+
* touch dispatch. Keeping them apart is the whole point of the type.
|
|
20
|
+
*
|
|
21
|
+
* The pipeline is three pure stages:
|
|
22
|
+
* register → boot-fail-fast (throws — a bad manifest never reaches
|
|
23
|
+
* runtime)
|
|
24
|
+
* resolve → per-request, per-persona: enabledIds ∩ registry, capped,
|
|
25
|
+
* unprovisioned serverKey manifests DROPPED (never a
|
|
26
|
+
* mid-turn failure — a missing key degrades to "not
|
|
27
|
+
* offered" and is reported back for UI display)
|
|
28
|
+
* buildDispatch → the ONE place a resolved manifest becomes a ToolDef,
|
|
29
|
+
* closing over the env-var NAME (never the key value) so
|
|
30
|
+
* the key is read fresh at call time and never serialized
|
|
31
|
+
* onto the manifest object or persisted anywhere.
|
|
32
|
+
*
|
|
33
|
+
* Law 8: when a second (server-side) host consumes this registry — a proxy
|
|
34
|
+
* or worker dispatching tool calls outside the browser — the env-var
|
|
35
|
+
* resolution and the drop-on-unprovisioned rule this module owns must
|
|
36
|
+
* extract to a shared place in THAT change, not be hand-duplicated. Nothing
|
|
37
|
+
* here assumes a browser; `env` is passed in, never read from a global.
|
|
38
|
+
*/
|
|
39
|
+
import { defineTool } from './tools.js';
|
|
40
|
+
const TOP_LEVEL_ALLOWED = new Set(['type', 'properties', 'required', 'description']);
|
|
41
|
+
const PROPERTY_ALLOWED = new Set(['type', 'enum', 'description']);
|
|
42
|
+
/** checkInput (tools.js) only reads top-level `required` / per-property
|
|
43
|
+
* `type` / per-property `enum`. Anything else in the schema (oneOf, $ref,
|
|
44
|
+
* pattern, items, nested objects, additionalProperties…) would silently
|
|
45
|
+
* never be enforced — so registration rejects it instead of shipping a
|
|
46
|
+
* manifest whose declared contract lies about what's actually checked. */
|
|
47
|
+
function unsupportedSchemaFeature(schema) {
|
|
48
|
+
if (!schema || typeof schema !== 'object' || Array.isArray(schema)) {
|
|
49
|
+
return 'inputSchema must be an object';
|
|
50
|
+
}
|
|
51
|
+
for (const key of Object.keys(schema)) {
|
|
52
|
+
if (!TOP_LEVEL_ALLOWED.has(key)) {
|
|
53
|
+
return `uses unsupported top-level keyword "${key}" (checkInput only supports type/properties/required)`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if ('required' in schema && !Array.isArray(schema['required'])) {
|
|
57
|
+
return '"required" must be an array of strings';
|
|
58
|
+
}
|
|
59
|
+
if ('properties' in schema) {
|
|
60
|
+
const properties = schema['properties'];
|
|
61
|
+
if (!properties || typeof properties !== 'object' || Array.isArray(properties)) {
|
|
62
|
+
return '"properties" must be an object';
|
|
63
|
+
}
|
|
64
|
+
for (const [name, prop] of Object.entries(properties)) {
|
|
65
|
+
if (!prop || typeof prop !== 'object' || Array.isArray(prop)) {
|
|
66
|
+
return `property "${name}" schema must be an object`;
|
|
67
|
+
}
|
|
68
|
+
for (const key of Object.keys(prop)) {
|
|
69
|
+
if (!PROPERTY_ALLOWED.has(key)) {
|
|
70
|
+
return `property "${name}" uses unsupported keyword "${key}" (checkInput only supports type/enum)`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
export function createIntegrationRegistry() {
|
|
78
|
+
const byId = new Map();
|
|
79
|
+
const toolNameOwner = new Map();
|
|
80
|
+
return {
|
|
81
|
+
register(manifest) {
|
|
82
|
+
if (byId.has(manifest.id)) {
|
|
83
|
+
throw new Error(`createIntegrationRegistry: duplicate integration id "${manifest.id}"`);
|
|
84
|
+
}
|
|
85
|
+
const existingOwner = toolNameOwner.get(manifest.tool.name);
|
|
86
|
+
if (existingOwner) {
|
|
87
|
+
throw new Error(`createIntegrationRegistry: duplicate tool name "${manifest.tool.name}" — ` +
|
|
88
|
+
`already registered by integration "${existingOwner}" (integration "${manifest.id}")`);
|
|
89
|
+
}
|
|
90
|
+
const schemaProblem = unsupportedSchemaFeature(manifest.tool.inputSchema);
|
|
91
|
+
if (schemaProblem) {
|
|
92
|
+
throw new Error(`createIntegrationRegistry "${manifest.id}": inputSchema ${schemaProblem}`);
|
|
93
|
+
}
|
|
94
|
+
if (manifest.auth?.kind === 'serverKey' && !manifest.auth.envKey) {
|
|
95
|
+
throw new Error(`createIntegrationRegistry "${manifest.id}": auth.envKey is required and non-empty for kind "serverKey"`);
|
|
96
|
+
}
|
|
97
|
+
byId.set(manifest.id, manifest);
|
|
98
|
+
toolNameOwner.set(manifest.tool.name, manifest.id);
|
|
99
|
+
return manifest;
|
|
100
|
+
},
|
|
101
|
+
get(id) {
|
|
102
|
+
return byId.get(id);
|
|
103
|
+
},
|
|
104
|
+
list() {
|
|
105
|
+
return [...byId.values()];
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** Documented cap — resolveIntegrations never hands more than this many
|
|
110
|
+
* manifests to one dispatch, regardless of how many a persona enables. */
|
|
111
|
+
export const MAX_INTEGRATIONS = 16;
|
|
112
|
+
/** enabledIds ∩ registry, capped at MAX_INTEGRATIONS, then any serverKey
|
|
113
|
+
* manifest whose env var is unset in `env` is dropped (reason reported).
|
|
114
|
+
* Order matches the contract's own wording: intersect → cap → drop, so a
|
|
115
|
+
* persona enabling more than the cap never sees a key-provisioning check
|
|
116
|
+
* applied to an integration it wouldn't have gotten a slot for anyway. */
|
|
117
|
+
export function resolveIntegrations(registry, enabledIds, env) {
|
|
118
|
+
const intersected = [];
|
|
119
|
+
const seen = new Set();
|
|
120
|
+
for (const id of enabledIds) {
|
|
121
|
+
if (seen.has(id))
|
|
122
|
+
continue;
|
|
123
|
+
seen.add(id);
|
|
124
|
+
const manifest = registry.get(id);
|
|
125
|
+
if (manifest)
|
|
126
|
+
intersected.push(manifest);
|
|
127
|
+
}
|
|
128
|
+
const capped = intersected.slice(0, MAX_INTEGRATIONS);
|
|
129
|
+
const resolved = [];
|
|
130
|
+
const dropped = [];
|
|
131
|
+
for (const manifest of capped) {
|
|
132
|
+
if (manifest.auth?.kind === 'serverKey' && !env[manifest.auth.envKey]) {
|
|
133
|
+
dropped.push({
|
|
134
|
+
id: manifest.id,
|
|
135
|
+
reason: `unprovisioned: env var "${manifest.auth.envKey}" is not set`,
|
|
136
|
+
});
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
resolved.push(manifest);
|
|
140
|
+
}
|
|
141
|
+
return { resolved, dropped };
|
|
142
|
+
}
|
|
143
|
+
/** The ONE place resolved manifests become `{ tools: ToolDef[] }` for
|
|
144
|
+
* AgentConfig. Each ToolDef's `execute` closes over `env` and the auth's
|
|
145
|
+
* envKey NAME only — the key VALUE is read fresh from `env` at call time,
|
|
146
|
+
* never stored on the manifest, never serialized. Schema validation is
|
|
147
|
+
* NOT repeated here: `executeTool` (tools.js, driving every ToolDef
|
|
148
|
+
* through the loop) already runs `checkInput` before invoking `execute` —
|
|
149
|
+
* wrapping it again here would check twice for one call. Zero resolved
|
|
150
|
+
* manifests returns `{}` (no `tools` key at all), so an agent with no
|
|
151
|
+
* integrations enabled produces the exact same AgentConfig, and the same
|
|
152
|
+
* outbound request, as one that never knew integrations existed (law 2). */
|
|
153
|
+
export function buildToolDispatch(resolved, env) {
|
|
154
|
+
if (!resolved.length)
|
|
155
|
+
return {};
|
|
156
|
+
const tools = resolved.map(manifest => defineTool({
|
|
157
|
+
name: manifest.tool.name,
|
|
158
|
+
...(manifest.tool.description ? { description: manifest.tool.description } : {}),
|
|
159
|
+
inputSchema: manifest.tool.inputSchema,
|
|
160
|
+
execute: (input, ctx) => {
|
|
161
|
+
const key = manifest.auth?.kind === 'serverKey' ? env[manifest.auth.envKey] : undefined;
|
|
162
|
+
return manifest.execute(input, key !== undefined ? { ...ctx, key } : ctx);
|
|
163
|
+
},
|
|
164
|
+
}));
|
|
165
|
+
return { tools };
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=integrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrations.js","sourceRoot":"","sources":["src/integrations.ts"],"names":[],"mappings":"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"}
|
package/loop.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn loop — stream → tool_use → execute → tool_result → continue.
|
|
3
|
+
*
|
|
4
|
+
* One agent.send() = one runLoop(). Each round streams a model response;
|
|
5
|
+
* tool calls are executed (gated by onToolCall when provided) and fed back
|
|
6
|
+
* as tool_result parts, then the loop re-enters. A round with no tool calls
|
|
7
|
+
* is the final round: the loop emits `done` and returns.
|
|
8
|
+
*
|
|
9
|
+
* Bounded by maxToolRounds: on exhaustion the loop emits `done` with the
|
|
10
|
+
* synthetic stopReason 'max_tool_rounds' (loop-level signal, not a
|
|
11
|
+
* provider value — the adapter-level never-normalize rule is untouched).
|
|
12
|
+
*
|
|
13
|
+
* The loop maintains its OWN working message list; the caller's Session is
|
|
14
|
+
* never mutated here (reduce() is the single session writer). The events
|
|
15
|
+
* this generator yields, folded through reduce(), reconstruct exactly the
|
|
16
|
+
* messages the loop appended internally — one contract, two consumers.
|
|
17
|
+
*
|
|
18
|
+
* Progress markers (law 3): the loop emits ONLY the stages it genuinely
|
|
19
|
+
* reaches — `sent` before every provider call, `retry` before a call that
|
|
20
|
+
* repeats a round after tool feedback (i.e. round > 0), `tool` before each
|
|
21
|
+
* tool executes, `done` right before the terminal `done` event on both
|
|
22
|
+
* exit paths. The other vocabulary entries (`started`/`reasoning`/
|
|
23
|
+
* `content`/`validating`) belong to signals this loop doesn't independently
|
|
24
|
+
* observe today — inventing an emission point for them would violate the
|
|
25
|
+
* honesty guard, so they stay declared-but-unemitted here.
|
|
26
|
+
*/
|
|
27
|
+
import type { ChatOpts, LLMClient, ToolUse } from '@adia-ai/llm';
|
|
28
|
+
import type { AgentEvent } from './events.js';
|
|
29
|
+
import type { Msg } from './session.js';
|
|
30
|
+
import { type ToolContext, type ToolDef } from './tools.js';
|
|
31
|
+
export interface LoopOpts {
|
|
32
|
+
client: LLMClient;
|
|
33
|
+
/** Per-call ChatOpts overrides (model, system, cache, temperature…). */
|
|
34
|
+
chat?: Partial<ChatOpts>;
|
|
35
|
+
tools: ToolDef[];
|
|
36
|
+
maxToolRounds: number;
|
|
37
|
+
/** Gate every tool call before it executes. Return false to deny — the
|
|
38
|
+
* model receives an isError tool_result and the loop continues. The
|
|
39
|
+
* caller owns escalation (same contract as validate-and-repair). */
|
|
40
|
+
onToolCall?: (call: ToolUse, ctx: ToolContext) => boolean | Promise<boolean>;
|
|
41
|
+
ctx: ToolContext;
|
|
42
|
+
}
|
|
43
|
+
export declare function runLoop(messages: Msg[], opts: LoopOpts): AsyncGenerator<AgentEvent>;
|
|
44
|
+
//# sourceMappingURL=loop.d.ts.map
|
package/loop.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["src/loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAQ,OAAO,EAAgB,MAAM,cAAc,CAAC;AACrF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAwB,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAElF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB;;yEAEqE;IACrE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,GAAG,EAAE,WAAW,CAAC;CAClB;AAED,wBAAuB,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CA2F1F"}
|
package/loop.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turn loop — stream → tool_use → execute → tool_result → continue.
|
|
3
|
+
*
|
|
4
|
+
* One agent.send() = one runLoop(). Each round streams a model response;
|
|
5
|
+
* tool calls are executed (gated by onToolCall when provided) and fed back
|
|
6
|
+
* as tool_result parts, then the loop re-enters. A round with no tool calls
|
|
7
|
+
* is the final round: the loop emits `done` and returns.
|
|
8
|
+
*
|
|
9
|
+
* Bounded by maxToolRounds: on exhaustion the loop emits `done` with the
|
|
10
|
+
* synthetic stopReason 'max_tool_rounds' (loop-level signal, not a
|
|
11
|
+
* provider value — the adapter-level never-normalize rule is untouched).
|
|
12
|
+
*
|
|
13
|
+
* The loop maintains its OWN working message list; the caller's Session is
|
|
14
|
+
* never mutated here (reduce() is the single session writer). The events
|
|
15
|
+
* this generator yields, folded through reduce(), reconstruct exactly the
|
|
16
|
+
* messages the loop appended internally — one contract, two consumers.
|
|
17
|
+
*
|
|
18
|
+
* Progress markers (law 3): the loop emits ONLY the stages it genuinely
|
|
19
|
+
* reaches — `sent` before every provider call, `retry` before a call that
|
|
20
|
+
* repeats a round after tool feedback (i.e. round > 0), `tool` before each
|
|
21
|
+
* tool executes, `done` right before the terminal `done` event on both
|
|
22
|
+
* exit paths. The other vocabulary entries (`started`/`reasoning`/
|
|
23
|
+
* `content`/`validating`) belong to signals this loop doesn't independently
|
|
24
|
+
* observe today — inventing an emission point for them would violate the
|
|
25
|
+
* honesty guard, so they stay declared-but-unemitted here.
|
|
26
|
+
*/
|
|
27
|
+
import { executeTool, toSpecs } from './tools.js';
|
|
28
|
+
export async function* runLoop(messages, opts) {
|
|
29
|
+
const working = [...messages];
|
|
30
|
+
const total = { input: 0, output: 0, cacheCreation: 0, cacheRead: 0 };
|
|
31
|
+
const specs = toSpecs(opts.tools);
|
|
32
|
+
const byName = new Map(opts.tools.map(t => [t.name, t]));
|
|
33
|
+
for (let round = 0; round < opts.maxToolRounds; round++) {
|
|
34
|
+
let text = '';
|
|
35
|
+
let stopReason = 'end';
|
|
36
|
+
const calls = [];
|
|
37
|
+
if (round > 0)
|
|
38
|
+
yield { type: 'progress', stage: 'retry' };
|
|
39
|
+
yield { type: 'progress', stage: 'sent' };
|
|
40
|
+
const stream = opts.client.stream({
|
|
41
|
+
...opts.chat,
|
|
42
|
+
messages: working,
|
|
43
|
+
...(specs.length ? { tools: specs } : {}),
|
|
44
|
+
...(opts.ctx.signal ? { signal: opts.ctx.signal } : {}),
|
|
45
|
+
});
|
|
46
|
+
for await (const chunk of stream) {
|
|
47
|
+
if (chunk.type === 'text') {
|
|
48
|
+
text = chunk.snapshot;
|
|
49
|
+
yield { type: 'text', text: chunk.text, snapshot: chunk.snapshot };
|
|
50
|
+
}
|
|
51
|
+
else if (chunk.type === 'thinking') {
|
|
52
|
+
yield { type: 'thinking', text: chunk.text };
|
|
53
|
+
}
|
|
54
|
+
else if (chunk.type === 'tool_use') {
|
|
55
|
+
calls.push({ id: chunk.id, name: chunk.name, input: chunk.input });
|
|
56
|
+
yield { type: 'tool_use', id: chunk.id, name: chunk.name, input: chunk.input };
|
|
57
|
+
}
|
|
58
|
+
else if (chunk.type === 'done') {
|
|
59
|
+
stopReason = chunk.stopReason;
|
|
60
|
+
// The adapter's done.text is authoritative — a client emitting
|
|
61
|
+
// empty snapshots on word chunks still yields the full final text.
|
|
62
|
+
if (chunk.text)
|
|
63
|
+
text = chunk.text;
|
|
64
|
+
total.input += chunk.usage.input;
|
|
65
|
+
total.output += chunk.usage.output;
|
|
66
|
+
total.cacheCreation = (total.cacheCreation ?? 0) + (chunk.usage.cacheCreation ?? 0);
|
|
67
|
+
total.cacheRead = (total.cacheRead ?? 0) + (chunk.usage.cacheRead ?? 0);
|
|
68
|
+
}
|
|
69
|
+
else if (chunk.type === 'error') {
|
|
70
|
+
yield { type: 'error', error: chunk.error };
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (!calls.length) {
|
|
75
|
+
yield { type: 'progress', stage: 'done' };
|
|
76
|
+
yield { type: 'done', text, usage: total, stopReason };
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Assistant turn: text (when present) + the tool_use parts, then one
|
|
80
|
+
// tool message carrying every result — mirrors reduce()'s folding.
|
|
81
|
+
const assistantParts = [
|
|
82
|
+
...(text ? [{ type: 'text', text }] : []),
|
|
83
|
+
...calls.map(c => ({ type: 'tool_use', id: c.id, name: c.name, input: c.input })),
|
|
84
|
+
];
|
|
85
|
+
working.push({ role: 'assistant', content: assistantParts });
|
|
86
|
+
const resultParts = [];
|
|
87
|
+
for (const call of calls) {
|
|
88
|
+
yield { type: 'progress', stage: 'tool' };
|
|
89
|
+
const tool = byName.get(call.name);
|
|
90
|
+
let outcome;
|
|
91
|
+
if (!tool) {
|
|
92
|
+
outcome = { output: `Unknown tool "${call.name}"`, isError: true };
|
|
93
|
+
}
|
|
94
|
+
else if (opts.onToolCall && (await opts.onToolCall(call, opts.ctx)) === false) {
|
|
95
|
+
outcome = { output: `Tool call "${call.name}" denied`, isError: true };
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
outcome = await executeTool(tool, call.input, opts.ctx);
|
|
99
|
+
}
|
|
100
|
+
resultParts.push({
|
|
101
|
+
type: 'tool_result',
|
|
102
|
+
toolUseId: call.id,
|
|
103
|
+
name: call.name,
|
|
104
|
+
content: outcome.output,
|
|
105
|
+
...(outcome.isError ? { isError: true } : {}),
|
|
106
|
+
});
|
|
107
|
+
yield {
|
|
108
|
+
type: 'tool_result',
|
|
109
|
+
id: call.id,
|
|
110
|
+
name: call.name,
|
|
111
|
+
output: outcome.output,
|
|
112
|
+
...(outcome.isError ? { isError: true } : {}),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
working.push({ role: 'tool', content: resultParts });
|
|
116
|
+
}
|
|
117
|
+
yield { type: 'progress', stage: 'done' };
|
|
118
|
+
yield { type: 'done', text: '', usage: total, stopReason: 'max_tool_rounds' };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=loop.js.map
|
package/loop.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["src/loop.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adia-ai/agent",
|
|
3
|
+
"version": "0.8.26",
|
|
4
|
+
"description": "Composable chat-agent harness — assemble an agent from four declared parts (prompt layers, tools, workflows, resources) on top of @adia-ai/llm. Owns the tool-call loop, the session model, and the one shared event reducer. Works in browser and Node.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"import": "./index.js",
|
|
10
|
+
"default": "./index.js"
|
|
11
|
+
},
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"*.js",
|
|
16
|
+
"*.d.ts",
|
|
17
|
+
"*.d.ts.map",
|
|
18
|
+
"*.js.map",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"!**/*.test.js"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc --build tsconfig.build.json",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@adia-ai/llm": "^0.8.0"
|
|
29
|
+
},
|
|
30
|
+
"sideEffects": false,
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"registry": "https://registry.npmjs.org"
|
|
34
|
+
},
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/adiahealth/gen-ui-kit.git",
|
|
38
|
+
"directory": "packages/agent"
|
|
39
|
+
},
|
|
40
|
+
"license": "MIT"
|
|
41
|
+
}
|