@namzu/sdk 50.1.0 → 51.0.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/CHANGELOG.md +18 -0
- package/dist/execution/code-runtime/types.d.ts +35 -0
- package/dist/execution/code-runtime/types.d.ts.map +1 -1
- package/dist/execution/code-runtime/types.js.map +1 -1
- package/dist/execution/code-runtime/worker-program.d.ts +1 -1
- package/dist/execution/code-runtime/worker-program.d.ts.map +1 -1
- package/dist/execution/code-runtime/worker-program.js +72 -13
- package/dist/execution/code-runtime/worker-program.js.map +1 -1
- package/dist/execution/code-runtime/worker.d.ts.map +1 -1
- package/dist/execution/code-runtime/worker.js +35 -1
- package/dist/execution/code-runtime/worker.js.map +1 -1
- package/dist/execution/workflow/errors.d.ts +5 -0
- package/dist/execution/workflow/errors.d.ts.map +1 -0
- package/dist/execution/workflow/errors.js +8 -0
- package/dist/execution/workflow/errors.js.map +1 -0
- package/dist/execution/workflow/index.d.ts +9 -0
- package/dist/execution/workflow/index.d.ts.map +1 -0
- package/dist/execution/workflow/index.js +6 -0
- package/dist/execution/workflow/index.js.map +1 -0
- package/dist/execution/workflow/journal.d.ts +18 -0
- package/dist/execution/workflow/journal.d.ts.map +1 -0
- package/dist/execution/workflow/journal.js +43 -0
- package/dist/execution/workflow/journal.js.map +1 -0
- package/dist/execution/workflow/meta.d.ts +14 -0
- package/dist/execution/workflow/meta.d.ts.map +1 -0
- package/dist/execution/workflow/meta.js +314 -0
- package/dist/execution/workflow/meta.js.map +1 -0
- package/dist/execution/workflow/phases.d.ts +32 -0
- package/dist/execution/workflow/phases.d.ts.map +1 -0
- package/dist/execution/workflow/phases.js +57 -0
- package/dist/execution/workflow/phases.js.map +1 -0
- package/dist/execution/workflow/prelude.d.ts +15 -0
- package/dist/execution/workflow/prelude.d.ts.map +1 -0
- package/dist/execution/workflow/prelude.js +128 -0
- package/dist/execution/workflow/prelude.js.map +1 -0
- package/dist/execution/workflow/runtime.d.ts +31 -0
- package/dist/execution/workflow/runtime.d.ts.map +1 -0
- package/dist/execution/workflow/runtime.js +682 -0
- package/dist/execution/workflow/runtime.js.map +1 -0
- package/dist/execution/workflow/schema.d.ts +10 -0
- package/dist/execution/workflow/schema.d.ts.map +1 -0
- package/dist/execution/workflow/schema.js +145 -0
- package/dist/execution/workflow/schema.js.map +1 -0
- package/dist/execution/workflow/types.d.ts +267 -0
- package/dist/execution/workflow/types.d.ts.map +1 -0
- package/dist/execution/workflow/types.js +7 -0
- package/dist/execution/workflow/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +2 -1
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/process/kill-tree.d.ts +7 -0
- package/dist/process/kill-tree.d.ts.map +1 -1
- package/dist/process/kill-tree.js +41 -0
- package/dist/process/kill-tree.js.map +1 -1
- package/dist/provider/token-budget.d.ts.map +1 -1
- package/dist/provider/token-budget.js +31 -2
- package/dist/provider/token-budget.js.map +1 -1
- package/dist/public-runtime.d.ts +1 -0
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +3 -0
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +1 -1
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +1 -1
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +3 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/jobs/job-id.d.ts +21 -0
- package/dist/runtime/jobs/job-id.d.ts.map +1 -0
- package/dist/runtime/jobs/job-id.js +66 -0
- package/dist/runtime/jobs/job-id.js.map +1 -0
- package/dist/runtime/jobs/registry.d.ts +0 -1
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +2 -3
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/prompt.d.ts.map +1 -1
- package/dist/runtime/query/prompt.js +5 -1
- package/dist/runtime/query/prompt.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts +8 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +20 -3
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/job.d.ts.map +1 -1
- package/dist/tools/builtins/job.js +4 -0
- package/dist/tools/builtins/job.js.map +1 -1
- package/dist/tools/builtins/wait-for-job.d.ts.map +1 -1
- package/dist/tools/builtins/wait-for-job.js +4 -0
- package/dist/tools/builtins/wait-for-job.js.map +1 -1
- package/dist/tools/command-shell.d.ts +55 -0
- package/dist/tools/command-shell.d.ts.map +1 -1
- package/dist/tools/command-shell.js +174 -13
- package/dist/tools/command-shell.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/AGENTS.md +134 -46
- package/src/execution/code-runtime/types.ts +37 -1
- package/src/execution/code-runtime/worker-program.ts +72 -13
- package/src/execution/code-runtime/worker.ts +40 -1
- package/src/execution/workflow/errors.ts +7 -0
- package/src/execution/workflow/index.ts +8 -0
- package/src/execution/workflow/journal.ts +46 -0
- package/src/execution/workflow/meta.ts +316 -0
- package/src/execution/workflow/phases.ts +91 -0
- package/src/execution/workflow/prelude.ts +135 -0
- package/src/execution/workflow/runtime.ts +786 -0
- package/src/execution/workflow/schema.ts +137 -0
- package/src/execution/workflow/types.ts +300 -0
- package/src/index.ts +4 -0
- package/src/plugin/shell-hook.ts +2 -1
- package/src/process/kill-tree.ts +43 -0
- package/src/provider/token-budget.ts +31 -1
- package/src/public-runtime.ts +11 -0
- package/src/public-tools.ts +6 -0
- package/src/public-types.ts +3 -0
- package/src/runtime/jobs/job-id.ts +66 -0
- package/src/runtime/jobs/registry.ts +2 -3
- package/src/runtime/query/prompt.ts +5 -1
- package/src/tools/builtins/bash.ts +33 -3
- package/src/tools/builtins/job.ts +4 -0
- package/src/tools/builtins/wait-for-job.ts +4 -0
- package/src/tools/command-shell.ts +194 -11
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { normalizePhaseTitle } from './meta.js'
|
|
2
|
+
import type {
|
|
3
|
+
WorkflowAgentState,
|
|
4
|
+
WorkflowPhaseMeta,
|
|
5
|
+
WorkflowPhaseStatus,
|
|
6
|
+
WorkflowPhaseSummary,
|
|
7
|
+
} from './types.js'
|
|
8
|
+
|
|
9
|
+
export interface PhaseRecord {
|
|
10
|
+
readonly index: number
|
|
11
|
+
readonly title: string
|
|
12
|
+
readonly declared: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Phase titles of one run. A title is the only grouping key: the same title
|
|
17
|
+
* is the same group. Indexes are 1-based first-seen order, declared titles
|
|
18
|
+
* first. `register` reports whether the title was announced just now.
|
|
19
|
+
*/
|
|
20
|
+
export class PhaseRegistry {
|
|
21
|
+
private readonly byTitle = new Map<string, PhaseRecord>()
|
|
22
|
+
|
|
23
|
+
register(rawTitle: string, declared = false): { phase: PhaseRecord; isNew: boolean } {
|
|
24
|
+
const title = normalizePhaseTitle(rawTitle)
|
|
25
|
+
const existing = this.byTitle.get(title)
|
|
26
|
+
if (existing) return { phase: existing, isNew: false }
|
|
27
|
+
const phase = { index: this.byTitle.size + 1, title, declared }
|
|
28
|
+
this.byTitle.set(title, phase)
|
|
29
|
+
return { phase, isNew: true }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
all(): PhaseRecord[] {
|
|
33
|
+
return [...this.byTitle.values()]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface PhaseAgentView {
|
|
38
|
+
readonly phaseIndex?: number
|
|
39
|
+
readonly state: WorkflowAgentState
|
|
40
|
+
readonly tokens: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function statusOf(total: number, done: number, failed: number): WorkflowPhaseStatus {
|
|
44
|
+
if (total === 0) return 'not-started'
|
|
45
|
+
if (done + failed === total) return failed > 0 ? 'failed' : 'done'
|
|
46
|
+
return 'running'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Per-phase status from the agents seen so far, in phase order. A phase with
|
|
51
|
+
* no agent yet is `not-started`. When no agent belongs to any phase (and
|
|
52
|
+
* nothing is declared) the run shows one derived group, "Agents"; agents
|
|
53
|
+
* without a phase next to phased ones also land in "Agents", listed last.
|
|
54
|
+
*/
|
|
55
|
+
export function summarizeWorkflowPhases(
|
|
56
|
+
declared: readonly WorkflowPhaseMeta[],
|
|
57
|
+
phases: readonly PhaseRecord[],
|
|
58
|
+
agents: readonly PhaseAgentView[],
|
|
59
|
+
): WorkflowPhaseSummary[] {
|
|
60
|
+
const detail = new Map(declared.map((p) => [normalizePhaseTitle(p.title), p.detail]))
|
|
61
|
+
const summarize = (
|
|
62
|
+
index: number,
|
|
63
|
+
title: string,
|
|
64
|
+
members: readonly PhaseAgentView[],
|
|
65
|
+
extra?: string,
|
|
66
|
+
): WorkflowPhaseSummary => {
|
|
67
|
+
const done = members.filter((a) => a.state === 'done').length
|
|
68
|
+
const failed = members.filter((a) => a.state === 'error').length
|
|
69
|
+
return {
|
|
70
|
+
index,
|
|
71
|
+
title,
|
|
72
|
+
...(extra !== undefined ? { detail: extra } : {}),
|
|
73
|
+
status: statusOf(members.length, done, failed),
|
|
74
|
+
agents: members.length,
|
|
75
|
+
done,
|
|
76
|
+
failed,
|
|
77
|
+
tokens: members.reduce((sum, a) => sum + a.tokens, 0),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const out = phases.map((p) =>
|
|
81
|
+
summarize(
|
|
82
|
+
p.index,
|
|
83
|
+
p.title,
|
|
84
|
+
agents.filter((a) => a.phaseIndex === p.index),
|
|
85
|
+
detail.get(p.title),
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
const ungrouped = agents.filter((a) => a.phaseIndex === undefined)
|
|
89
|
+
if (ungrouped.length > 0) out.push(summarize(0, 'Agents', ungrouped))
|
|
90
|
+
return out
|
|
91
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interpreter-side half of the workflow language: `agent`, `parallel`,
|
|
3
|
+
* `pipeline`, `phase`, `log`, `args` and `budget`.
|
|
4
|
+
*
|
|
5
|
+
* This text runs INSIDE the QuickJS interpreter, ahead of the script body,
|
|
6
|
+
* and is the only place those names are defined. It captures the two bridge
|
|
7
|
+
* natives (`call`, `print`) in its own closure and deletes them from the
|
|
8
|
+
* global object, so the script reaches the host only through `agent()`, and
|
|
9
|
+
* `phase()`/`log()` can only emit well-formed records. None of this is a
|
|
10
|
+
* security boundary: the host re-validates every request and treats every
|
|
11
|
+
* printed line as untrusted text. The boundary is the interpreter itself.
|
|
12
|
+
*
|
|
13
|
+
* Written with String.raw and no backticks or substitutions so no escaping
|
|
14
|
+
* layer can change what the interpreter parses.
|
|
15
|
+
*/
|
|
16
|
+
const PRELUDE_SOURCE = String.raw`(function (config) {
|
|
17
|
+
'use strict';
|
|
18
|
+
var rawCall = globalThis.call;
|
|
19
|
+
var rawPrint = globalThis.print;
|
|
20
|
+
delete globalThis.call;
|
|
21
|
+
delete globalThis.print;
|
|
22
|
+
var stringify = JSON.stringify;
|
|
23
|
+
var spent = { tokensUsed: 0 };
|
|
24
|
+
var cursor = null;
|
|
25
|
+
function emit(record) { rawPrint(stringify(record)); }
|
|
26
|
+
function clean(value, limit) {
|
|
27
|
+
return String(value).replace(/\s+/g, ' ').trim().slice(0, limit);
|
|
28
|
+
}
|
|
29
|
+
function phase(title) {
|
|
30
|
+
var t = clean(title, 120);
|
|
31
|
+
if (!t) throw new TypeError('phase() needs a non-empty title.');
|
|
32
|
+
cursor = t;
|
|
33
|
+
emit({ k: 'phase', title: t });
|
|
34
|
+
}
|
|
35
|
+
function log(message) {
|
|
36
|
+
emit({ k: 'log', message: String(message).slice(0, 2000) });
|
|
37
|
+
}
|
|
38
|
+
function kind(value) {
|
|
39
|
+
if (value === null) return 'null';
|
|
40
|
+
if (value === '') return 'an empty string';
|
|
41
|
+
if (Array.isArray(value)) return 'an array';
|
|
42
|
+
var t = typeof value;
|
|
43
|
+
if (t === 'undefined') return 'undefined';
|
|
44
|
+
if (t === 'object') return typeof value.then === 'function' ? 'a promise' : 'an object';
|
|
45
|
+
return 'a ' + t;
|
|
46
|
+
}
|
|
47
|
+
async function agent(prompt, opts) {
|
|
48
|
+
if (typeof prompt !== 'string' || prompt.length === 0) {
|
|
49
|
+
throw new TypeError('agent(prompt, options?): the prompt must be a non-empty string, got ' + kind(prompt));
|
|
50
|
+
}
|
|
51
|
+
var o = opts == null ? {} : opts;
|
|
52
|
+
if (typeof o !== 'object' || Array.isArray(o)) {
|
|
53
|
+
throw new TypeError('agent(prompt, options?): options must be an object, got ' + kind(o));
|
|
54
|
+
}
|
|
55
|
+
var request = { prompt: prompt, cursor: cursor };
|
|
56
|
+
if (o.label != null) request.label = clean(o.label, 120);
|
|
57
|
+
if (o.phase != null) request.phase = clean(o.phase, 120);
|
|
58
|
+
if (o.schema != null) request.schema = o.schema;
|
|
59
|
+
if (o.agentType != null) request.agentType = clean(o.agentType, 120);
|
|
60
|
+
if (o.model != null) request.model = clean(o.model, 120);
|
|
61
|
+
if (o.effort != null) request.effort = clean(o.effort, 32);
|
|
62
|
+
var reply = await rawCall('agent', request);
|
|
63
|
+
spent.tokensUsed = reply.t;
|
|
64
|
+
return reply.v;
|
|
65
|
+
}
|
|
66
|
+
async function parallel(thunks) {
|
|
67
|
+
if (!Array.isArray(thunks)) {
|
|
68
|
+
throw new TypeError('parallel(thunks): the argument must be an array of functions, got ' + kind(thunks));
|
|
69
|
+
}
|
|
70
|
+
for (var p = 0; p < thunks.length; p++) {
|
|
71
|
+
if (typeof thunks[p] !== 'function') {
|
|
72
|
+
throw new TypeError('parallel(thunks): item ' + (p + 1) + ' must be a function (wrap the work as () => agent(...)), got ' + kind(thunks[p]));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return Promise.all(thunks.map(function (t) { return t(); }));
|
|
76
|
+
}
|
|
77
|
+
async function pipeline(items) {
|
|
78
|
+
if (!Array.isArray(items)) {
|
|
79
|
+
throw new TypeError('pipeline(items, ...stages): the first argument must be an array, got ' + kind(items));
|
|
80
|
+
}
|
|
81
|
+
var stages = Array.prototype.slice.call(arguments, 1);
|
|
82
|
+
for (var s = 0; s < stages.length; s++) {
|
|
83
|
+
if (typeof stages[s] !== 'function') {
|
|
84
|
+
throw new TypeError('pipeline(items, ...stages): stage ' + (s + 1) + ' must be a function, got ' + kind(stages[s]));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return Promise.all(items.map(async function (item, index) {
|
|
88
|
+
var value = item;
|
|
89
|
+
for (var i = 0; i < stages.length; i++) {
|
|
90
|
+
value = await stages[i](value, index, item);
|
|
91
|
+
if (value === null || value === undefined) return null;
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
var budget = Object.freeze({
|
|
97
|
+
get tokensUsed() { return spent.tokensUsed; },
|
|
98
|
+
get tokenLimit() { return config.tokenLimit === null ? undefined : config.tokenLimit; },
|
|
99
|
+
});
|
|
100
|
+
function install(name, value) {
|
|
101
|
+
Object.defineProperty(globalThis, name, { value: value, writable: false, configurable: false, enumerable: true });
|
|
102
|
+
}
|
|
103
|
+
install('agent', agent);
|
|
104
|
+
install('parallel', parallel);
|
|
105
|
+
install('pipeline', pipeline);
|
|
106
|
+
install('phase', phase);
|
|
107
|
+
install('log', log);
|
|
108
|
+
install('budget', budget);
|
|
109
|
+
install('args', config.args);
|
|
110
|
+
})`
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Lines the prelude occupies in the interpreter source, plus the newline that
|
|
114
|
+
* joins it to the script body: subtract this from an interpreter line number
|
|
115
|
+
* to get the line in the script the author wrote.
|
|
116
|
+
*/
|
|
117
|
+
export function preludeLineCount(config: {
|
|
118
|
+
args: unknown
|
|
119
|
+
tokenLimit: number | null
|
|
120
|
+
}): number {
|
|
121
|
+
return buildPrelude(config).split('\n').length
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Source that installs the workflow globals, ready to prepend to a script body. */
|
|
125
|
+
export function buildPrelude(config: {
|
|
126
|
+
args: unknown
|
|
127
|
+
tokenLimit: number | null
|
|
128
|
+
}): string {
|
|
129
|
+
const literal = JSON.stringify(config)
|
|
130
|
+
.split(String.fromCharCode(0x2028))
|
|
131
|
+
.join('\\u2028')
|
|
132
|
+
.split(String.fromCharCode(0x2029))
|
|
133
|
+
.join('\\u2029')
|
|
134
|
+
return `${PRELUDE_SOURCE}(${literal});`
|
|
135
|
+
}
|